我正在尝试多次传递孩子的孩子的裁判,但它不起作用。我有一个名为AvatarBuilder
的功能组件,它使用了Avatars
组件。该组件呈现Avatar
个组件的列表。这个想法是在AvatarBuilder
中引用每个Avatar
组件。
以下是摘要代码段:
const AvatarBuilder = props => {
...
// in this dummy example i would have 5 avatars
const URLS=[1,2,3,4,5];
const refs = URLS.map(item => ({ ref: React.createRef() }));
return (
<>
<Avatars
ref={refs}
urlList={URLS}
/>
</>
);
const Avatars = React.forwardRef((props, ref) => {
let urlList = props.urlList.map((url, index) => {
return (
<Avatar
ref={ref[index].ref}
url={url}
/>
)
})
return (
<ul className="Avatars" >
{urlList}
</ul>
)
});
const Avatar = React.forwardRef((props, ref) => {
return (
<li className="Avatar">
<img
src={props.url}
ref={ref}
/>
</li>
)
});
我收到以下警告,并且在安装所有组件时,refs数组未更新。
index.js:1 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Check the render method of `ForwardRef`.
in h (at Avatar.js:11)
in li (at Avatar.js:10)
in ForwardRef (at Avatars.js:10)
in ul (at Avatars.js:24)
in ForwardRef (at AvatarBuilder.js:189)
in AvatarBuilder (at App.js:19)
in div (at App.js:14)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
任何想法应该如何解决?谢谢!
答案 0 :(得分:1)
对于功能组件,必须使用useRef而不是React.createRef,因为将在render中创建新的ref实例。
如果您使用React.createRef,请利用useMemo记住参考
const AvatarBuilder = props => {
// in this dummy example i would have 5 avatars
const URLS=[1,2,3,4,5];
const refs = React.useMemo(() =>URLS.map(item => ({ ref: React.createRef() })), []); // create refs only once
React.useEffect(() => {
console.log(refs);
},[])
return (
<Avatars
ref={refs}
urlList={URLS}
/>
);
}
const Avatars = React.forwardRef((props, ref) => {
let urlList = props.urlList.map((url, index) => {
return (
<Avatar
ref={ref[index].ref}
url={url}
/>
)
})
return (
<ul className="Avatars" >
{urlList}
</ul>
)
});
const Avatar = React.forwardRef((props, ref) => {
return (
<li className="Avatar">
<img
src={props.url}
ref={ref}
/>
</li>
)
});
ReactDOM.render(<AvatarBuilder/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app"/>
答案 1 :(得分:0)
尝试这个。
const AvatarBuilder = props => {
...
// in this dummy example i would have 5 avatars
const URLS=[1,2,3,4,5];
const refs = URLS.map(item => React.createRef());
return (
<>
<Avatars
refs={refs}
urlList={URLS}
/>
</>
);
// you don't need to make it with `fowardRef()`
const Avatars = (props) => {
const {refs} = props;
let urlList = props.urlList.map((url, index) => {
console.log(url, index, typeof (index), ref);
return (
<Avatar
ref={refs[index]}
url={url}
/>
)
})
return (
<ul className="Avatars" >
{urlList}
</ul>
)
};
const Avatar = React.forwardRef((props, ref) => {
return (
<li className="Avatar">
<img
src={props.url}
ref={ref}
/>
</li>
)
});