当前位置:  开发笔记 > 编程语言 > 正文

通过React.cloneElement维护组件引用

如何解决《通过React.cloneElement维护组件引用》经验,为你挑选了1个好方法。

我一直在测试使用React.cloneElement()扩展组件的可能的局限性/危险性children。我发现的一种可能的危险是可能会覆盖诸如ref和的道具key

但是,根据React的0.13版本候选对象(早在2015年):

但是,与JSX和cloneWithProps不同,它还保留引用。这意味着,如果您得到一个带有裁判的孩子,则不会意外地从祖先那里偷走它。您将获得与新元素相同的引用。

[...]

注意:React.cloneElement(child, { ref: 'newRef' })确实会覆盖该引用,因此除非您使用回调引用,否则两个父母仍然不可能对同一个孩子拥有一个引用。

我编写了一个小的React应用程序,该应用程序克隆了推入的子组件,并在两个级别上测试ref的有效性:

class ChildComponent extends React.Component{
  constructor(props){
    super(props);   

    this.onClick = this.onClick.bind(this);
    this.extendsChildren = this.extendChildren(this);
  }

  onClick(e) {
    e.preventDefault();

    try{
      alert(this._input.value);
    }catch(e){
      alert('ref broken :(');
    }
  }

  extendChildren(){
    return React.Children.map(this.props.children, child => {
      return React.cloneElement(
        child,
        {
          ref: ref => this._input = ref
        }
      );
    });
  }

  render() {
    return(
      
{this.extendChildren()}
); } } class AncestorComponent extends React.Component{ constructor(props){ super(props); this.onClick = this.onClick.bind(this); } onClick(e) { e.preventDefault(); try{ alert(this._input.value); }catch(e){ alert('ref broken :('); } } render() { return (

The expected behaviour is that I should be able to click on both Application and ChildComponent check buttons and have a reference to the input (poping an alert with the input's value).

this._input = ref} defaultValue="Hello World"/>
); } }

但是,ChildComponent内部的cloningElements会覆盖ref输入字段中的AncestorComponent的prop,我希望在该字段ref中保留该prop,以及ref我定义为的新对象React.cloneElement

您可以通过运行CodePen进行测试。

我做错什么了吗,或者此功能此后被删除了?



1> Prusprus..:

根据Dan Abramov的响应,即使使用回调,覆盖引用仍将覆盖引用。您需要在回调声明中调用当前引用:

return React.Children.map(this.props.children, child =>
  React.cloneElement(child, {
    ref(node) {
      // Keep your own reference
      this._input = node;
      // Call the original ref, if any
      const {ref} = child;
      if (typeof ref === 'function') {
        ref(node);
      }
    }
  )
);

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有