React redux componentDidMount只运行一次

时间:2017-07-31 16:35:43

标签: reactjs

我使用react-reduxreact-router-dom来获取我的应用中的导航和状态,但我遇到了问题。我有以下路线设置。

<Provider store={this.store}>
    <BrowserRouter>
        <Switch>
            <Route path="/profile" component={Profile} store={this.store}/>
            <Route path="/clients" component={Clients} store={this.store}/>
        </Switch>
    </BrowserRouter>
</Provider>

然后我有一个名为Profile的子组件,它试图读取上下文存储。它工作正常,但只是第一次。我尽可能简化了这一点。

class Profile extends React.Component {

    constructor(props, context) {
    super(props, context);
    this.state = {};

}

componentDidMount() {

    console.log('Called once');
    this.store = this.context.store;
    this.unsubscribe = this.store.subscribe(() => {

        this.forceUpdate();
        const user = this.store.getState().profile.userDetails;
        this.setState({user});

    });
}


componentWillUnmount() {

    console.log('unsubscribe');
    this.unsubscribe();

}

这意味着一旦我离开页面并返回,就没有商店可供使用,因此它无法呈现组件。谁能告诉我这里缺少什么?

3 个答案:

答案 0 :(得分:1)

您可以使用componentDidUpdate来解决此问题:

componentDidUpdate() {
    this.store = this.context.store;
    const user = this.store.getState().profile.userDetails;
    if (this.state.user.id !== user.id)
        this.setState({user});
}

答案 1 :(得分:1)

真的不你应该如何使用redux。您应该在应用的起始点初始化商店,然后只连接个人资料。

class Profile extends Component {
   constructor(props) {
      super(props);
      this.state = {};
   }

   render() {
     return (<div>{this.props.userDetails}</div>);
   }
}

const mapStateToProps = (state, ownProps) => {
  userDetails: state.profiles[ownProps.userId].userDetails
};

export default connect(
   mapStateToProps
)(Profile);

您还应该管理从较高范围传递配置文件ID。

答案 2 :(得分:1)

您可以使用redux商店的方式是利用connect HOC提供的react-redux.这样您就不必订阅商店并通过商店作为道具的路线

import {connect} from 'react-redux';

class Profile extends React.Component {

    constructor(props, context) {
       super(props, context);
       this.state = {};
    }   
    render() {
      return <div>{this.props.user}</div>
    }

}

const mapStateToProps = (state)  => {
  return {
    user: state.profile.userDetails
  }
}

export default connect(mapStateToProps)(Profile);
----------

<Provider store={this.store}>
    <BrowserRouter>
        <Switch>
            <Route path="/profile" component={Profile} store={this.store}/>
            <Route path="/clients" component={Clients} store={this.store}/>
        </Switch>
    </BrowserRouter>
</Provider>