![](/img/trans.png)
[英]React props.children is not rerendering after first state change
[英]Rerendering React props.children
我有这样的设置:
// inside Parent.js
class Parent extends React.Component {
render() {
return { this.props.children }
}
}
// inside Child.js
class Child extends React.Component {
render() {
let message;
const greet = this.context.store.parentState.greet;
if(greet) message = 'Hello, world!';
return (
<div>
{ message }
</div>
)
}
}
Child.contextTypes = {
store: PropTypes.object.isRequired
}
// inside App.js
<Parent>
<Route path='/a-path' component={ Child } />
</Parent>
当Parent
通过setState
接收新状态时, render
调用其render
方法,但不调用Child
的render
方法!
我想要实现的原因是因为Child
某些逻辑依赖于Parent
的状态。
如果我通过context
传递Parent
的状态,比如传递store
方式,然后通过this.context.parentState
在Child
访问它,这似乎正在工作并导致调用Child
的render
方法,我想这是因为我们'重新接受新的context
。
为什么是这样? context
是伟大的,但有没有解决这个特定问题的好办法,而无需context
?
如果您将组件渲染为子组件(不是Route的组件),则可以将React.cloneElement
与React.Children.map
React.cloneElement
使用
// inside Parent.js
class Parent extends React.Component {
render() {
return React.Children.map(this.props.children, (child) =>
React.cloneElement(child, {parentState: this.state.parentState})
);
}
}
但是,如果呈现为Children to Parent的元素是Routes,那么您需要使用上下文或在Route
周围编写一个包装器,以便Route接收的任何额外的props传递给组件
const RouteWrapper = ({exact, path, component: Component, anyOtherRouterProp, ...rest}) =>
<Route exact={exact} path={path} {...otherRouterProps} render={(props) => <Component {...props} {...rest} />} />
在上述情况下, anyOtherRouterProp
是适用于Route
的道具,需要单独进行解构。 在此之后,您可以使用React.Children.map和React.cloneElement将道具传递给子项。
虽然这是一种这样的方式,我仍然建议你使用上下文,特别是引入new context API
,这使得它非常容易实现
你可以这样做....
// inside Parent.js
class Parent extends React.Component {
render() {
return (
<Child children={this.props.children} />
)
}
}
// inside Child.js
class Child extends React.Component {
render() {
let message;
const greet = this.context.store.parentState.greet;
if(greet) message = 'Hello, world!';
return (
<div>
{ message }
{ this.props.children }
</div>
)
}
}
Child.contextTypes = {
store: PropTypes.object.isRequired
}
// inside App.js
<Parent>
<Route path='/a-path' component={ Child } />
</Parent>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.