我有一个包含许多子节点的React(15.5.4)组件,其中一些是HTML元素,另一些是其他React组件。
我使用服务器呈现并且需要在服务器和客户端上执行相同的操作。客户端将使用React的生产版本。
我需要迭代子节点并识别特定类型的React组件。所以我的第一个想法是使用React.Children.forEach()
进行迭代并查找组件名称。
React.Children.forEach(this.props.children, child => {
console.log('name =', child.name)
})
似乎child.name
和child.displayName
不存在。
现在,child.type
存在,并且是一个字符串(对于HTML元素),如"ul"
或一个函数(对于React组件)。
当它是一个函数时,我可以像lodash/get
一样使用const type = get(child, 'type.name', '')
来获取组件名称。 但是,这似乎只适用于服务器,而不是客户端生产版本,它返回一个字符串:"t"
。看起来开发版本使用我的组件名称作为函数,但生成版本将其重命名为t()
。所以我无法使用child.type.name
。
我如何:
答案 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;
答案 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>)
}
}