具有直接子项的组件的 CSSTransition nodeRef

CSSTransition nodeRef for component with direct children

我想在使用 react-transition-group 时摆脱 findDOMNodeStrictMode 的警告,但我偶然发现了一个问题。

我的 <Slide> 组件如下所示:

class Slide extends React.Component {
  nodeRef = React.createRef();

  render() {
    return (
      <CSSTransition
        in={this.props.in}
        timeout={ANIMATION_DURATION}
        mountOnEnter={true}
        unmountOnExit={true}
        classNames={{
          enter: "slideEnter",
          enterActive: "slideEnterActive",
          exit: "slideExit",
          exitActive: "slideExitActive"
        }}
        nodeRef={this.nodeRef}
      >
        {this.props.children}
      </CSSTransition>
    );
  }
}

它接收一个 Drawer 元素作为子元素,Drawer 组件如下所示:

class Drawer extends React.Component {
  render() {
    return (
      <div className="drawer">
        <button onClick={this.props.onClose}>close me</button>{" "}
        <div>This is my drawer</div>
      </div>
    );
  }
}

我无法用 HTML 标签包裹 children 元素(以附加引用 <div ref={this.nodeRef}>{this.props.children}</div>,因为它会破坏内容的动画效果。(我正在为儿童使用它是绝对位置的不同抽屉)

我也试过 cloneElement 但它仍然不起作用(下面的代码表现如下:1. in 没有动画,2. out 没有动画,3。in 动画有效,但我收到警告 findDOMNode,因此 nodeRef 似乎作为 null 发送,4。out 动画无效。

const onlyChild = React.Children.only(this.props.children);
const childWithRef = React.cloneElement(onlyChild, {
  ref: this.nodeRef;
});

这种情况有什么解决办法吗?谢谢!

问题是 nodeRef 需要指向一个 DOM 节点,顾名思义,在你的例子中它指向 Drawer [=30= 的一个实例].您有两个选择:

  1. 通过另一个 prop 传递 ref,例如forwardedRef,并在 Drawer class 中将该道具传递给根元素:
React.cloneElement(onlyChild, {
  forwardedRef: this.nodeRef,
})
<div ref={this.props.forwardedRef} className="drawer">
  1. Drawer转换为函数组件并使用React.forwardRef:
const Drawer = React.forwardRef((props, ref) => {
  return (
    <div ref={ref} className="drawer">
      <button onClick={props.onClose}>close me</button>{" "}
      <div>This is my drawer</div>
    </div>
  );
});