React Transition Group:如何将ref传递到映射组件以避免警告:findDOMNode在Strict



我有以下代码来渲染带有动画安装/卸载的过滤列表:

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添加一个ref(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>
)
}

但是,我不能在映射回调中使用useRef,因为不允许在回调中使用钩子。

我试图创建一个refs数组(目标DOM如何在地图中使用useRef进行反应(:

function List({ list, templates, 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, templates, transition }) {
return (
<TransitionGroup 
className="wscfl-list"
component="ul"
>
{list.map((item) => (
<Content item={item} key={item.id} templates={templates} transition={transition}/>
))}
</TransitionGroup>
);
}

最新更新