作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前在我的 React 应用程序中收到以下错误:
Function components cannot be given refs. Attempts to access this refwill fail. Did you mean to use React.forwardRef()?
const Services: FunctionComponent = (): ReactElement => {
const servicesRef = useRef(null);
return (
<Layout>
<ServicesList ref={servicesRef} />
</Layout>
);
};
export default Services;
const ServicesList: React.FunctionComponent = ({ children }: Props) => {
return (
<section className="my-24 md:my-32">
{children && children}
</section>
);
};
export default ServicesList;
最佳答案
forwardRef
api,(与 useImperativeHandle
Hook )允许您自定义 refs 在自定义组件中的放置方式和位置。此外,forwardRef 是将 ref 传递给自定义函数组件的唯一方法。
首先,重要的是要理解 refs 在类组件、函数组件和常规 DOM 元素上的工作方式不同。
来自 docs :
The value of the ref differs depending on the type of the node:
- When the ref attribute is used on an HTML element, the ref created inthe constructor with React.createRef() receives the underlying DOMelement as its current property.
- When the ref attribute is used on acustom class component, the ref object receives the mounted instanceof the component as its current.
- You may not use the ref attribute onfunction components because they don’t have instances.
function AutoFocusInput() {
const inputRef = useRef(null);
// This effect runs only once after the component mounts (like componentDidMount)
useEffect(() => {
// refs on regular DOM elements (e.g. the "input" tag) have access to the DOM node
inputRef.current.focus();
}, []);
return <input ref={inputRef} />
}
2. 类组件上的 Ref 让我们可以访问实例及其所有方法和字段:
class Child extends Component {
state = {color: "red"}
toggleColor = () => this.setState({color: this.state.color === "red" ? "blue" : "red"})
render() {
return <div style={{backgroundColor: this.state.color}}>yo</div>
}
}
class Parent extends Component {
childRef = createRef();
handleButtonClicked = () => {
// refs on class components: hold the class component instance,
// allowing us to call its methods!
this.childRef.current.toggleColor();
}
render() {
return (
<div>
<button onClick={this.handleButtonClicked}>toggle color!</button>
<Child ref={childRef} />
</div>
);
}
}
3. 现在,终于回答你的问题了。 Refs 不能传递给函数组件,因为它们没有实例!
// Only when using forwardRef, the function component receives two arguments,
// props and ref (Normally the component only gets the props argument).
const RedInput = forwardRef((props, ref) => {
// passing the ref to a DOM element,
// so that the parent has a reference to the DOM node
return <input style={{color: "red"}} {...props} ref={ref} />
});
function AutoFocusInput() {
const inputRef = useRef(null);
// This effect runs only once after the component mounts (like componentDidMount)
useEffect(() => {
// ref on function component is forwarded to a regular DOM element,
// so now the parent has access to the DOM node including its focus method.
// Note that the ref usage is the same as a regular
// DOM element, like in example 1!
inputRef.current.focus();
}, []);
return <RedInput ref={inputRef} />
}
3.2 将父 ref 附加到自定义对象:
const Child = forwardRef((props, ref) => {
const [color, setColor] = useState("red");
// To customize the value that the parent will get in their ref.current:
// pass the ref object to useImperativeHandle as the first argument.
// Then, whatever will be returned from the callback in the second argument,
// will be the value of ref.current.
// Here I return an object with the toggleColor method on it, for the parent to use:
useImperativeHandle(ref, () => ({
toggleColor: () => setColor(prevColor => prevColor === "red" ? "blue" : "red")
}));
return <div style={{backgroundColor: color}}>yo</div>;
});
class Parent extends Component {
childRef = createRef();
handleButtonClicked = () => {
// Ref passed to a function component wrapped in forwardRef.
// Note that nothing has changed for this Parent component
// compared with the class component in example 2!
this.childRef.current.toggleColor();
}
render() {
return (
<div>
<button onClick={this.handleButtonClicked}>toggle color!</button>
<Child ref={childRef} />
</div>
);
}
}
关于javascript - 如何在 React 中使用 forwardRef()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66664209/
我是一名优秀的程序员,十分优秀!