ReactJS - React.Children.forEach - 我可以获取子组件名称吗?

时间:2017-05-11 10:39:04

标签: javascript reactjs

我有一个包含许多子节点的React(15.5.4)组件,其中一些是HTML元素,另一些是其他React组件。

我使用服务器呈现并且需要在服务器和客户端上执行相同的操作。客户端将使用React的生产版本。

我需要迭代子节点并识别特定类型的React组件。所以我的第一个想法是使用React.Children.forEach()进行迭代并查找组件名称。

React.Children.forEach(this.props.children, child => {
  console.log('name =', child.name)
})

似乎child.namechild.displayName不存在。

现在,child.type存在,并且是一个字符串(对于HTML元素),如"ul"或一个函数(对于React组件)。

当它是一个函数时,我可以像lodash/get一样使用const type = get(child, 'type.name', '')来获取组件名称。 但是,这似乎只适用于服务器,而不是客户端生产版本,它返回一个字符串:"t"。看起来开发版本使用我的组件名称作为函数,但生成版本将其重命名为t()。所以我无法使用child.type.name

我如何:

  1. 迭代组件子组件并识别特定类型的组件..?
  2. 哪个适用于开发和生产React构建..?

4 个答案:

答案 0 :(得分:12)

您可以在属性displayName中设置组件的名称。如果您正在使用ES6类,则可以将名为displayName的静态属性设置为组件类。然后,您将能够使用child.type.displayName获取子名称。



const FirstChild = ({ name }) => <li>{name}</li>;
FirstChild.displayName = 'FirstChild';

const SecondChild = ({ name }) => <li>{name}</li>;
SecondChild.displayName = 'SecondChild';

class ThirdChild extends React.Component {
  static displayName = 'ThirdChild';
  
  render() {
    return (
      <li>{this.props.name}</li>
    );
  }
  
}

class Parent extends React.Component {
  componentDidMount() {
    React.Children.forEach(this.props.children, child => {
      console.log('name =', child.type.displayName);
    })
  }
  
  render() {
    return (
      <ul>{this.props.children}</ul>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <Parent>
        <FirstChild name='1st child value' />
        <SecondChild name='2nd child value' />
        <ThirdChild name='3rd child value' />
      </Parent>
    );
  }
}


ReactDOM.render(<App />, document.getElementById("app"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果您使用的是Babel,则可以使用此Babel插件自动设置displayName,以便child.type.displayName等于您为该组件命名的字符串:

https://www.npmjs.com/package/babel-plugin-add-react-displayname

易于安装和使用,只需阅读说明并确保将插件名add-react-displayname添加到.babelrc文件中的插件数组中。

答案 2 :(得分:0)

使用es6传播算子:

        React.Children.forEach(children, child => {
            const childType = { ...child.type }
            console.log('child', childType.displayName)
        })

答案 3 :(得分:0)

function MyComponent() (
  return <AnotherComponent />
)

// In React Function Component ?
function AnotherComponent({children}) {

    console.log(children.type.name) // result = 'MyComponent' 

    return (<div></div>)
}

// In React Class Component ?
export default class Extends React.Component {

    console.log(this.children.type.name) // result = 'MyComponent' 

    render() {
      return (<div></div>)
    }

}