繁体   English   中英

使用React.cloneElement()保留的引用

[英]Refs preserved with React.cloneElement()

我不明白在React官方文档中写的声明:

cloneElement()

 React.cloneElement( element, [props], [...children] ) 

使用element作为起点克隆并返回一个新的React元素。 结果元素将具有原始元素的道具,新道具以浅层方式合并。 新的孩子将取代现有的孩子。 key和ref将保留原始元素。

React.cloneElement()几乎相当于:

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

但是,它也保留了refs。 这意味着,如果你的孩子有一个参考,你不会意外地从你的祖先窃取它。 您将获得与新元素相同的参考。

让我困惑的是声明这意味着如果你有一个带有参考的孩子,你就不会意外地从你的祖先那里偷走它。 您将获得与新元素相同的参考。

如果我理解正常,即使父克隆,也会保留指向父组件中的子元素的引用。 因此,在React.cloneElement(Parent) ,有两个单独的React.cloneElement(Parent) (内部具有相同的深度值,包括ref),并且两者都分别具有ref,并且那些refs指向同一个Child。 我是否正确?

那么祖先的作用是什么? 在这种情况下,祖先是什么?

为了举例说明文档看起来是什么样的,我们可以考虑一个组件App,它呈现一个组件Main ,它有两个孩子Home和Dashboard,它指定了refs

class App extends React.Component {
   constructor(props) {
      super(props);
      this.homeRef = React.createRef();
      this.dashboardRef = React.createRef();
   }
   render() {
      return (
          <Main>
               <Home ref={this.homeRef} key={'Home'}/>
               <Dashboard ref={this.dashboardRef} key={'Dashboard'}/>
          </Main>
      )         
   }
}

现在主要组件克隆子元素以向其子元素添加道具onClick,

class Main extends React.Component {
   onClick = () => {}
   render() {
       return (
          <div>
              {/* Some content here */}
              {React.Children.map(this.props.children, child => {
                 return React.cloneElement(child, {onClick: this.onClick})
               })}
          </div>
       )
   }
}

现在,当Main组件克隆其中的子项时

React.cloneElement(child, {onClick: this.onClick})

在我们的例子中是Home和Dashboard组件,如果cloneElement忽略了key和由App组件传递给它的ref ,则App组件将无法访问它呈现的这些子组件。 因此,React.cloneElement保留传递给元素的引用和键,即使它们是在子渲染函数中克隆的。

由createdElement创建的组件是克隆子组件, <Main>使用的组件是克隆子组件,那么<App>中的ref是什么意思? 原来的孩子,还是克隆的孩子?

这句话是否意外窃取意味着禁止访问

只有元素在DOM中呈现时才能引用元素。 在上面的例子中,原始元素不会被渲染,但克隆元素是。 如果React没有为在DOM中呈现的克隆组件分配相同的引用,则App组件将不会与任何重要事件进行交互。 此外,如果您决定渲染原始孩子和克隆儿童,那么裁判将指向克隆儿童。

演示说明以上内容

PS CloneElement不用于克隆组件,而不是渲染JSX实例,主要是为了添加更多的道具

从其他地方渲染的子组件

我希望上面的例子解释了这个场景

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM