在Reducer中状态更改后,Redux连接的组件未重新呈现

时间:2018-06-21 09:39:52

标签: reactjs redux

这是我的减速器代码

const authReducer = (
  state = {
    isAuthenticated: !AuthService.isTokenExpired(),
    isFetching: false,
    profile: AuthService.getProfile(),
    error: null
  },
  action
) => {

  switch (action.type) {    
   case types.LOGOUT_SUCCESS:
   return Object.assign({}, state, {
      isAuthenticated: false,
      isFetching: false,
      profile: {},
      error: null
    })
    default:
      return state;
  }

combinereducer.js

export default combineReducers({
    apiDataReducer,
    auth: authReducer
});

Main.js

  import rootReducer from './reducers/combineReducers';
    import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
    imp

ort thunk from 'redux-thunk';

const middleware = process.env.NODE_ENV !== 'production' ?  [reduxImmutableStateInvariant(), thunk] :  [thunk];

export let store = createStore(rootReducer, applyMiddleware(...middleware));

render(
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>,
  document.getElementById('root')
);

Header.js

  import React, { Component } from 'react';

    import { connect } from 'react-redux';
    import { withRouter } from 'react-router-dom';
    import * as authActions from '../../actions/basicActions';
    import HeaderView from './HeaderView';
    //import authReducer from './reducers/authReducer';


    const mapStateToProps = ({ auth }) => ({
      auth
      });

      const mapDispatchToProps = dispatch => ({
        loginRequest: () => dispatch(authActions.loginRequest()),
        logoutSuccess: () => dispatch(authActions.logoutSuccess())
      });

      export default withRouter(
        connect(mapStateToProps, mapDispatchToProps)(HeaderView)
      );

HeaderView.js

  handleLogoutClick = () => {
    this.props.logoutSuccess();
    this.props.history.push({ pathname: '/' });
  };

  render() {

    const { auth } = this.props;
    return (
      <div>
        {auth.isAuthenticated ? (
          <div>
            <div>
              <table>
                <tbody>

                      <label>
                        <aonClick={this.handleLogoutClick}> Log Out </a>
                      </label>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
            <nav className="navbar navbar-default">
              <ul className="nav navbar-nav">
                <li key="1" id="1" onClick={this.handleClick}><Link to={'/page2'}>page2</Link></li>
              </ul>
            </nav>
          </div>
        ) : (
            <label className="Note">
              logged in{' '} <a onClick={this.handleLoginClick}> Log In </a>
              {' '} to continue.
                </label>
          )}
      </div>
    );
  }

这是我的容器组件,其中reducer auth中的状态更改未反映 SomeContainer.js

const mapStateToProps = ({ auth }) => ({
  auth
  });

  const mapDispatchToProps = dispatch => ({
  });

  export default connect(mapStateToProps, mapDispatchToProps)(SomeContainer);

在HeaderView.js中单击注销时,将调用LOGOUTSUCCESS操作,并且reducer'auth'更改对象中'isAuthenticated'的值,但是该更改不调用连接的Container的'mapStateToProps'函数,并且reducer'auth'的值相同也就是说,即使注销也是如此。

1 个答案:

答案 0 :(得分:0)

因为当父级发生prop更改时,子级组件不会重新呈现。您可以将connect HoC视为HeaderView组件的父级。选中此question,以获取有关重新渲染条件的更多信息。

您需要使用state来更改componentWillReceiveProps。在HeaderView.js文件中:

constructor(props) {
      super(props);
      this.state = {
         isAuthenticated = false
      }
}

componentWillReceiveProps(nextProps) {
     if(nextProps.auth.isAuthenticated !== this.props.auth.isAuthenticated) {
        this.setState({isAuthenticated: nextProps.auth.isAuthenticated});
     }
}

handleLogoutClick = () => {
    this.props.logoutSuccess();
    this.props.history.push({ pathname: '/' });
  };

render() {

    const { isAuthenticated } = this.state;
    return (
      <div>
        {isAuthenticated ? (
          <div>
            <div>
              <table>
                <tbody>

                      <label>
                        <aonClick={this.handleLogoutClick}> Log Out </a>
                      </label>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
            <nav className="navbar navbar-default">
              <ul className="nav navbar-nav">
                <li key="1" id="1" onClick={this.handleClick}><Link to={'/page2'}>page2</Link></li>
              </ul>
            </nav>
          </div>
        ) : (
            <label className="Note">
              logged in{' '} <a onClick={this.handleLoginClick}> Log In </a>
              {' '} to continue.
                </label>
          )}
      </div>
    );
  }