【问题标题】:Is this a bug in React.cloneElement?这是 React.cloneElement 中的错误吗?
【发布时间】:2017-07-23 13:40:16
【问题描述】:

React's documentation 说:

React.cloneElement() 几乎等同于:

<element.type {...element.props} {...props}>{children}</element.type>

但是,它也保留了 refs。这意味着如果你得到一个带有 ref 的孩子,你不会不小心从你的祖先那里偷走它。您将获得附加到新元素的相同 ref。

所以我做了这个小例子:

import React, { Component, Children, cloneElement } from 'react';

class Wrapper extends Component {
    render() {
        return cloneElement(Children.only(this.props.children), {
            ref: (ref) => {
                console.log("wrapper", ref);
            },
        });
    }
}

const MyComponent = () =>
    <Wrapper>
        <div ref={ref => {
            console.log("original", ref);
        }}>
            My content
        </div>
    </Wrapper>

export default MyComponent;

(小提琴:https://jsfiddle.net/pxho45um/)

我认为渲染MyComponent 会同时记录"wrapper" &lt;div&gt;...&lt;/div&gt; 和"original" &lt;div&gt;...&lt;/div&gt;,但似乎只调用了包装器引用回调。

这不是与文档相反吗?或者当 React 团队说“如果你得到一个带有 ref 的孩子,你就不会不小心从你的祖先那里偷走它”是什么意思?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    描述确实很混乱,因为React.cloneElement(element, _, [...children])中的child不是指[...children],而是element。

    但是,它(它指的是 React.cloneElement())也保留了 refs。这意味着如果你得到一个带有 ref 的孩子,你不会不小心从你的祖先那里偷走它。您将获得附加到新元素的相同 ref。

    让我们想象一下下面的场景,你有一个组件&lt;GrandParent /&gt;

      <Parent ref='parent'>
        <Child ref='child'>
        </Child>
      <Parent />
    

    现在 GrandParent 假定&lt;Child /&gt; 的引用是'child' 并且可能调用this.refs.child.doSomething()。

    但是,在previous version of react 中,如果您在&lt;Parent /&gt; 中克隆&lt;Child /&gt;,&lt;GrandParent /&gt; 将失去其对&lt;Child /&gt; 的所有权,并且不能再通过this.refs 调用它。正如您在当前版本中看到的那样,此问题已得到修复,因此无论何时克隆一个元素,其父元素仍可以引用该克隆。


    现在我有一个悬而未决的问题 - 如果您在 &lt;Parent /&gt; 中克隆两次 &lt;Child /&gt; 怎么办,&lt;GrandParent /&gt; 中的引用会发生什么情况 - 它指的是哪个克隆?我想答案是the last one。

    【讨论】:

    • 这里涉及的复杂性是完全避免引用和cloneElement 的一个很好的论据。
    猜你喜欢
    • 2013-05-04
    • 2011-09-28
    • 2012-09-15
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多