ReactJS + Redux:在子组件中使用(功能)组件包装器 + 分派(状态)进行无限渲染循环
ReactJS + Redux: Infinite render loop with (functional) Component wrapper + dispatch (state) in child Component
我创建了一个无限渲染循环,其中包含一个组件包装器和一个调用调度函数(以更改 redux 中的状态)的子组件,但我不明白为什么必须重新渲染该组件,因为 props不改变我。
包装器:
export default function(ComposedComponent){
class Authenticate extends Component {
componentWillMount(){
//If not logged in
if (!this.props.loggedIn){
this.context.router.history.replace({ pathname: '/login' });
}
console.log("Mount parent");
}
render(){
return(
<ComposedComponent {...this.props} />
);
}
}
Authenticate.propTypes = {
loggedIn: PropTypes.bool.isRequired
}
// Provide router in context for redirect
Authenticate.contextTypes = {
router: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
loggedIn: state.user.loggedIn
})
return connect(mapStateToProps)(Authenticate);
}
子组件:
class InternalArea extends Component {
componentDidMount(){
this.props.setTitle(this.props.title);
console.log("Mount child");
}
render(){
return(
<div>
This is an internal area for logged in users.
</div>
);
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
setTitle
}, dispatch)
export default connect(
null,
mapDispatchToProps
)(InternalArea);
Wrapper 在 App.js 中被集成为 Route(PropsRoute 只是传递额外的 props):
<PropsRoute exact path="/internal-area" component={requireAuth(InternalArea)} title="Internal Area" />
删除子组件中的this.props.setTitle(this.props.title);
解决了循环错误,但我需要在那里调度它。还是我应该移动它?为什么会改变道具?
最后我弄明白了如何通过不使用功能包装器而是在 App.js 中接收路由组件作为子组件的包装器组件来创建此循环。此解决方案建议于:https://www.cuttlesoft.com/infinitely-dispatching-actions-react-redux-react-router-v4/
尽管如此,我并不是 100% 理解为什么会创建此循环。我有点困惑,功能包装器仍然是一种经常建议的重定向方法,尽管它似乎不适用于在子组件中调度 redux 操作。
我创建了一个无限渲染循环,其中包含一个组件包装器和一个调用调度函数(以更改 redux 中的状态)的子组件,但我不明白为什么必须重新渲染该组件,因为 props不改变我。
包装器:
export default function(ComposedComponent){
class Authenticate extends Component {
componentWillMount(){
//If not logged in
if (!this.props.loggedIn){
this.context.router.history.replace({ pathname: '/login' });
}
console.log("Mount parent");
}
render(){
return(
<ComposedComponent {...this.props} />
);
}
}
Authenticate.propTypes = {
loggedIn: PropTypes.bool.isRequired
}
// Provide router in context for redirect
Authenticate.contextTypes = {
router: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
loggedIn: state.user.loggedIn
})
return connect(mapStateToProps)(Authenticate);
}
子组件:
class InternalArea extends Component {
componentDidMount(){
this.props.setTitle(this.props.title);
console.log("Mount child");
}
render(){
return(
<div>
This is an internal area for logged in users.
</div>
);
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
setTitle
}, dispatch)
export default connect(
null,
mapDispatchToProps
)(InternalArea);
Wrapper 在 App.js 中被集成为 Route(PropsRoute 只是传递额外的 props):
<PropsRoute exact path="/internal-area" component={requireAuth(InternalArea)} title="Internal Area" />
删除子组件中的this.props.setTitle(this.props.title);
解决了循环错误,但我需要在那里调度它。还是我应该移动它?为什么会改变道具?
最后我弄明白了如何通过不使用功能包装器而是在 App.js 中接收路由组件作为子组件的包装器组件来创建此循环。此解决方案建议于:https://www.cuttlesoft.com/infinitely-dispatching-actions-react-redux-react-router-v4/
尽管如此,我并不是 100% 理解为什么会创建此循环。我有点困惑,功能包装器仍然是一种经常建议的重定向方法,尽管它似乎不适用于在子组件中调度 redux 操作。