对于正在构建的组件,我正在使用React.Children.map
递归地遍历其子组件以对其 Prop 进行修改。基本结构是这样的:
// main component
const Main = ({ children }) => recursivelyModifyChildProps(children);
// recursive function
function recursivelyModifyChildProps(children) {
return React.Children.map(children, (child) => {
// if no valid react element, just return it
if (!React.isValidElement(child)) {
return child;
}
// check if child isn't a `<Main/>` component
// not sure about this check
if (typeof child.type !== 'string' && child.type.name === 'Main') {
return child;
}
const { children, ...restProps } = child.props;
// do stuff to create new props
const newProps = { foo: 'bar' };
// return new element with modified props
return React.createElement(
child.type,
{
...restProps,
...newProps,
children: recursivelyModifyChildProps(children)
}
);
});
}
Main
的子代将通过recursivelyModifyChildProps
修改其 Prop ,而他们的子代将对其 Prop 进行修改,依此类推。除非子组件是Main
组件的实例,否则我想这样做,在这种情况下,应不加修改地返回它。目前,我正在通过child.type.name
做到这一点,并且确实可以。但是,我相信此实现非常容易出错,因为每个人都可以将其组件称为“Main”。弄清某个组件是一个实例(特定的(功能)组件还是其实例)的最佳(或至少更好)的方法是什么? 最佳答案
您可以通过比较child.type
和唯一的Main
实例来验证它。
if (child.type === Main) {
return undefined;
}
跳过
Main
实例修改所有Main
子级的完整示例。import React from 'react';
import ReactDOM from 'react-dom';
const Main = ({ children }) => recursivelyModifyChildProps(children);
function recursivelyModifyChildProps(children) {
return React.Children.map(children, child => {
if (!React.isValidElement(child)) {
return child;
}
if (child.type === Main) {
return undefined;
}
const { children, ...restProps } = child.props;
const newProps = { foo: 'bar' };
return React.createElement(child.type, {
...restProps,
...newProps,
children: recursivelyModifyChildProps(children)
});
});
}
const App = () => {
return (
<Main>
// v Main is skipped
<Main />
<div>Hello</div>
</Main>
);
};
ReactDOM.render(<App />, document.getElementById('root'));