如何解决React Transition Group:如何将 ref 传递给映射组件以避免警告:在 StrictMode
我有以下代码来渲染带有动画安装/卸载的过滤列表:
function List({ list,templates,transition }) {
return (
<TransitionGroup
className="wscfl-list"
component="ul"
>
{list.map((item) => (
<CSSTransition
key={item.id}
timeout={transition.timeout}
classNames={'wscfl-list__' + item.type + '-'}
>
<li className={'wscfl-list__' + item.type} >
<Item item={item} template={templates[item.type]} pkey={item.id}/>
</li>
</CSSTransition>
))}
</TransitionGroup>
);
}
这会抛出一个我想避免的 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead,add a ref directly to the element you want to reference.
。
我知道我应该向 CSSTransition (https://github.com/reactjs/react-transition-group/releases/tag/v4.4.0) 添加一个引用:
import React from "react"
import { CSSTransition } from "react-transition-group"
const MyComponent = () => {
const nodeRef = React.useRef(null)
return (
<CSSTransition nodeRef={nodeRef} in timeout={200} classNames="fade">
<div ref={nodeRef}>Fade</div>
</CSSTransition>
)
}
但是我不能在 map 回调中使用 useRef,因为它不允许在回调中使用钩子。
我尝试创建一个引用数组 (How target DOM with react useRef in map):
function List({ list,transition }) {
// https://stackoverflow.com/questions/54940399/how-target-dom-with-react-useref-in-map/55105849
const refsArray = [];
for (var i= 0; i < list.length; i++) {
refsArray.push(React.createRef());
}
let refs = React.useRef(refsArray);
React.useEffect(() => {
refs.current[0].current.focus()
},[]);
return (
<TransitionGroup
className="wscfl-list"
component="ul"
>
{list.map((item,i) => (
<CSSTransition
key={item.id}
nodeRef={refs.current[i]}
timeout={transition.timeout}
classNames={'wscfl-list__' + item.type + '-'}
>
<li ref={refs.current[i]} className={'wscfl-list__' + item.type} >
<Item item={item} template={templates[item.type]} pkey={item.id}/>
</li>
</CSSTransition>
))}
</TransitionGroup>
);
}
但这会在第一次渲染 TypeError: Cannot read property 'current' of undefined
时引发错误。
9 | }
10 | let refs = React.useRef(refsArray);
11 | React.useEffect(() => {
> 12 | refs.current[0].current.focus()
| ^ 13 | },[]);
14 | return (
15 | <TransitionGroup
有没有办法在不使用 findDOMNode 的情况下对映射组件使用 CSSTransition?
解决方法
无需使用引用数组即可处理此问题的最简单方法是提取另一个组件中的映射内容
const Content = ({item,transition,templates,...rest}) => {
const nodeRef = React.useRef(null)
return(
<CSSTransition
{...rest}
nodeRef={nodeRef}
timeout={transition.timeout}
classNames={'wscfl-list__' + item.type + '-'}
>
<li ref={nodeRef} className={'wscfl-list__' + item.type} >
<Item item={item} template={templates[item.type]} pkey={item.id}/>
</li>
</CSSTransition>
)
}
function List({ list,transition }) {
return (
<TransitionGroup
className="wscfl-list"
component="ul"
>
{list.map((item) => (
<Content item={item} key={item.id} templates={templates} transition={transition}/>
))}
</TransitionGroup>
);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。