是否有可能在没有渲染的情况下深入遍历React Children?

时间:2016-03-11 01:50:20

标签: javascript reactjs

有没有办法在bar下面'静态'获取所有<Wrapper/>个属性,例如没有渲染?

import React from 'react';
import ReactDOM from 'react-dom';

class Foo extends React.Component {
  render() {
    return(
      <div>
        <span bar="1" /> // want to collect this 'bar'
        <span bar="2" /> // want to collect this 'bar'
      </div>;
    );
  }
}


class FooTuple extends React.Component {
  render() {
    return(
      <div>
        <Foo />
        <Foo />
      </div>;
    );
  }
}

class Wrapper extends React.Component {
  render() {

    React.Children.forEach(this.props.children, child => {
      console.log(child.props); // can only see <FooTuple/> not <Foo/>
    });

    return(
      <div>
        {this.props.children}
      </div>;
    );
  }
}

ReactDOM.render(
  <Wrapper>
    <FooTuple />
  </Wrapper>, 
document.getElementById('app'));

这是一个尝试迭代child.children的天真尝试的webpackbin,这显然不起作用,但是如果它有用的话就在这里: http://www.webpackbin.com/EySeQ-ihg

1 个答案:

答案 0 :(得分:1)

TL; DR; 不可能。

-

我曾经遇到过同样的问题,试图遍历一棵深度嵌套的孩子的树。这是我的独家新闻:

必备知识

  • children是放置在jsx打开和关闭标签内的内容,或直接注入到儿童道具中的内容。 children道具之外的其他道具就是undefined

    <div className="wrapper">
      // Children
      <img src="url" />
    </div>
    
    /* OR */
    
    <div classname="wrapper" children={<img src="url" />}>
    
  • children是不透明的树状数据结构,代表了反应元素的树,React.createElement的输出可能是{{1} }在转译时实现。

    jsx
  • 创建{ $$typeof: Symbol(react.element), type: 'div', key: null, ref: null, props: { className: "wrapper", children: { $$typeof: Symbol(react.element), type: 'img', key: null, ref: null, props: { src: 'url' }, } } } 元素并不意味着它们已实例化,可以将它们视为描述符,React用于渲染这些元素。换句话说,React会在后台自行处理实例。

游玩孩子

让我们以您的示例为例,尝试遍历整棵树。

React

这些元素的不透明子对象是这样的:

<Wrapper>
  <FooTuple />
</Wrapper>

您可以看到{ $$typeof: Symbol(react.element), type: Wrapper, key: null, ref: null, props: { children: { $$typeof: Symbol(react.element), type: FooTuple, key: null, ref: null, props: {}, } } } 道具为空,这是您现在应该知道的原因。到达其子元素的唯一方法是使用其FooTuple实例化该元素,以便能够调用其render方法来获取其基础子元素,如下所示:

type

这显然根本不是要考虑的事情。

结论

没有一种干净的方法可以增加嵌套的孩子或从他们那里抓东西(例如您的箱子)。重构您的代码以另一种方式执行此操作。也许在class Wrapper extends React.Component { render() { React.Children.forEach(this.props.children, child => { const nestedChildren = new child.type(child.props).render(); console.log(nestedChildren); // `FooTuple` children }); return( <div> {this.props.children} </div>; ); } } 中提供了一个setter函数,以从任何深层次的孩子那里获得所需的数据。