【问题标题】:Unexpected behavior of React render propsReact 渲染道具的意外行为
【发布时间】:2021-08-05 22:23:57
【问题描述】:

我使用 React 转换组提出了以下代码:

const Transition = ({ elements, selectKey, render: Element, ...props }) => (
  <TransitionGroup {...props}>
    {elements.map((element) => (
      <CSSTransition
        key={selectKey(element)}
        timeout={1000}
        className="transition-slide"
      >
        <Element {...element} />
      </CSSTransition>
    ))}
  </TransitionGroup>
)

这里的关键部分是Transition 组件接收render 属性并应用一些转换来渲染它。

我期望它的工作方式:

<Transition render={(props) => <Toast {...props} />} />

但是这段代码并没有像我预期的那样工作:下一个元素的过渡中断前一个元素的过渡。

但是,这段代码可以正常工作:

const Element = (props) => <Toast {...props} />

// ...

<Transition render={Element} />

如何在不将所需的渲染道具放入单独的组件的情况下解决此问题?

代码沙盒:Example sandbox。沙盒提供了一个带有动画中断的不工作选项。要获得工作版本,您需要取消注释 /Toasts/index.js 文件中的第 16 行和第 30 行

附:我不能只使用render={Toast},因为我需要使用({id}) =&gt; &lt;Toast dismiss={() =&gt; {deleteToast(id)}} /&gt;。为了简化对问题的理解,我省略了这个细节。

【问题讨论】:

    标签: reactjs react-transition-group


    【解决方案1】:

    如果您不想将渲染函数放入另一个组件中,将其放入 useCallback() 为我解决了这个问题。

    const Toasts = () => {
      const [toasts, addToast] = useToasts();
    
      const Element = useCallback((props) => <Toast {...props} />, []);
    
      return (
        <div>
          <button onClick={addToast}>Add toast</button>
    
          <List>
            <Transition
              elements={toasts}
              selectKey={({ id }) => id}
              render={Element}
            />
          </List>
        </div>
      );
    }
    

    (我不太了解问题的根源,但它必须与函数引用有关。)

    【讨论】:

    • 我还决定使用useCallback 钩子,但这似乎很奇怪。甚至文档都说像 useCallbackuseMemo 这样的钩子仅用于优化目的,在这种情况下不能保证一致的行为
    • 是的,我也觉得很奇怪,这是为了快速解决问题,但我会更深入地研究文档,因为我真的很想知道导致这种行为的原因:D
    猜你喜欢
    • 1970-01-01
    • 2019-08-15
    • 2019-02-06
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    • 2022-01-20
    相关资源
    最近更新 更多