在将父元素的子元素包装到更高阶组件中然后进行渲染时,我目前遇到问题。
请考虑以下结构:
return (
<div className="App">
<FocusProvider>
<TestComponent testProp={'Foo'}/>
<TestComponent testProp={'Foo'}/>
<TestComponent testProp={'Foo'}/>
</FocusProvider>
</div>
);
其中FocusProvider
是父元素,TestComponent
是子元素,需要包装在一个更高阶的组件中,该组件为其提供生命周期方法并注入道具。
然后称为hoc
的高阶组件将覆盖TestComponent
的prop,并为其提供生命周期方法,如下所示:
const hoc = (WrappedComponent, prop) => {
return class extends React.Component {
shouldComponentUpdate = (prevProps, prop) => {
return !prevProps === prop
}
render(){
return <WrappedComponent testProp={prop}/>
}
}
}
FocusProvider
的呈现方法如下:
render(){
return(
this.props.children.map(child => {
let Elem = hoc(child, 'bar')
return <Elem/>
})
)
}
当我尝试渲染时,我得到Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
当我尝试将其更改为:
render(){
return(
this.props.children.map(child => {
let elem = hoc(child, 'bar')
return elem
})
)
}
渲染未返回任何内容。我很困惑,因为我可以直接渲染chil组件,但不能渲染HOC中包装的子组件:
render(){
return(
this.props.children.map(child => {
return child //This works
})
)
}
我想避免使用React.cloneElement
,因为我不想每次父级更新时都通过克隆子元素来触发重新渲染。
任何帮助将不胜感激
答案 0 :(得分:1)
hoc
是一个返回Component
而不是jsx
的函数。您不能将children
包裹在HOC
中。
但是您可以只包装FocusProvider
并使用cloneElement
将道具传递给孩子。这样使用cloneElement
不会有问题。实际上是common pattern。
function App() {
return (
<div className="App">
<FocusProvider bar="baz">
<Child />
<Child />
<Child />
</FocusProvider>
</div>
);
}
const withHOC = Component => props => {
return <Component foo="bar" {...props} />;
};
const FocusProvider = withHOC(({ children, foo, bar }) => {
return React.Children.map(children, child => {
return React.cloneElement(child, { foo, bar });
});
});
const Child = ({ foo, bar }) => (
<>
{foo}
{bar}
</>
);