gpt4 book ai didi

javascript - 如何在 React 中使用 forwardRef()?

转载 作者:行者123 更新时间:2023-12-03 17:22:27 25 4
gpt4 key购买 nike

我目前在我的 React 应用程序中收到以下错误:

Function components cannot be given refs. Attempts to access this refwill fail. Did you mean to use React.forwardRef()?


如何使用 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:

  1. 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.
  2. When the ref attribute is used on acustom class component, the ref object receives the mounted instanceof the component as its current.
  3. You may not use the ref attribute onfunction components because they don’t have instances.

以下是在不同元素类型上使用 refs 的方法示例:
1. DOM 元素上的 Ref 为您提供对 DOM 节点本身的引用:
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 不能传递给函数组件,因为它们没有实例!
将 ref 传递给函数组件的唯一方法是使用 forwardRef。使用 forwardRef 时,您可以简单地将 ref 传递给 DOM 元素,以便父级可以像示例 1 中那样访问它,或者您可以使用 useImperativeHandle 钩子(Hook)创建一个包含字段和方法的对象,这类似于示例 2。
3.1 简单地将 ref 传递给 DOM 元素:
// 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 附加到自定义对象:
要将函数或字段附加到 ref,就像您可以使用类组件的实例一样,您需要使用 `useImperativeHandle` 钩子(Hook):
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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com