Redux (с React) Оператор переключения редуктора НЕ обновляет состояние

Как следует из названия, я изо всех сил пытаюсь обновить состояние Redux с помощью редуктора. Я также использую Redux с React. В этом контексте я использую состояние Redux для хранения логического значения того, вошел ли пользователь в систему с помощью токена JWT. Я почти уверен, что мои редукторы настроены правильно, потому что я могу консоль выйти из исходного состояния аутентификации, которое по умолчанию установлено в false. НО, когда я запускаю действие AUTH_USER, которое сообщает редуктору обновить состояние до Authenticated = true, ничего не происходит. При регистрации состояния редукции auth оно остается ложным даже после того, как я запустил действие для AUTH_USER. Кажется, он правильно попадает в оператор switch в редукторе, потому что console.log отображается в терминале. Я получаю журнал консоли из метода жизненного цикла componentDidMount моего компонента заголовка, который отображается во всех частях моего приложения React.

Index.js редукторов (/src/reducers/index.js)

import { combineReducers } from 'redux';
import authReducer from './reducer_auth';

const rootReducer = combineReducers({
  auth: authReducer
});

export default rootReducer;

Редуктор аутентификации (/src/reducers/reducer_auth.js)

import { AUTH_USER, DEAUTH_USER } from '../actions/types';

export default function (state = { authenticated: false, error: "" }, 
action) {
  switch(action.type) {
    case AUTH_USER:
      console.log('THIS DOES SHOW UP IN CONSOLE')
      return {...state, error: "", authenticated: true };
    case DEAUTH_USER:
      return {...state, error: "", authenticated: false };
    default:
      return state;
  }
}

Создатель действий для входа в систему (/src/actions/index.js)

import axios from 'axios';
import history from '../utils/historyUtils';

import { AUTH_USER, DEAUTH_USER } from './types';

const ROOT_URL = 'http://localhost:8888';

export function signInUser(username, password) {
  const signInRequest = axios.post(`${ROOT_URL}/wp-json/jwt-auth/v1/token`, {
    "username": username,
    "password": password
  });

  return (dispatch) => {
    return signInRequest.then(response => {
      localStorage.setItem('token', JSON.stringify(response.data.token));

      dispatch({
        type: AUTH_USER,
        payload: { authenticated : true }
      })

      history.push('/');
      history.go();
    })
  }
}

Компонент заголовка (/src/containers/header.js)

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { signOutUser } from '../actions';

import '../styles/header.css';

class Header extends Component {
  componentDidMount() {
    console.log('authenticated from header: ', this.props.authenticated)
  }

  handleLogout(event) {
    event.preventDefault();
    localStorage.removeItem('token');

  }

  render() {
    return (
      <div className="container">
        <header>
          <div id="branding">
            <h1><Link to="/">INSERT BRAND HERE</Link></h1>
          </div>
          <nav>
            <ul>
              <li><Link to="/">Home</Link></li>
              <li><Link to="/contact">Contact</Link></li>
              <li><Link to="/services">Services</Link></li>
              <li><Link to="/Portfolio">Portfolio</Link></li>
              <li><Link to="/about">About</Link></li>
              <li><Link to="/blog">Blog</Link></li>
              {/* {this.props.authenticated ? <li>Logout</li> : <li><Link to="/signin">Login</Link></li>} */}
              <li><Link to="/signin">Login</Link></li>
            </ul>
          </nav>
        </header>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    authenticated: state.auth
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    signOutUser
  }, dispatch);
}

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

Index.js, содержащий маршруты (/src/index.js)

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import reduxThunk from 'redux-thunk';

import reducers from './reducers';
import Home from './components/home';
import About from './components/about';
import Blog from './containers/blog';
import Contact from './components/contact';
import Portfolio from './components/portfolio';
import Services from './components/services';
import registerServiceWorker from './registerServiceWorker';
import SignIn from './containers/signIn_form';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <BrowserRouter>
      <div>
        <Switch>
          <Route path="/about" component={About} />
          <Route path="/blog" component={Blog} />
          <Route path="/contact" component={Contact} />
          <Route path="/portfolio" component={Portfolio} />
          <Route path="/services" component={Services} />
          <Route path="/signin" component={SignIn} />
          <Route path="/" component={Home} />
        </Switch>
      </div>
    </BrowserRouter>
  </Provider>
, document.getElementById('root'));
registerServiceWorker();

Если бы кто-нибудь мог пролить свет на эту проблему, я был бы очень признателен!


person Calvin    schedule 15.11.2017    source источник
comment
вы говорите, что ничего не происходит, но вы не опубликовали код, в котором что-то могло бы произойти. где вы это регистрируете, ожидая, что состояние изменится?   -  person azium    schedule 15.11.2017
comment
Попался, позволь мне добавить это   -  person Calvin    schedule 15.11.2017
comment
Можете ли вы разместить свой index.js там, где вы используете <Route>   -  person Aaqib    schedule 15.11.2017
comment
Все обновлено, включая относительное расположение файлов!   -  person Calvin    schedule 15.11.2017
comment
В вашем штате нет auth собственности. В вашем mapStateToProps это authenticated: state.auth должно быть этим authenticated: state.authenticated.   -  person Rick Jolly    schedule 15.11.2017
comment
@RickJolly auth исходит из combineReducers   -  person azium    schedule 15.11.2017
comment
на самом деле это должно быть state.auth.authenticated   -  person azium    schedule 15.11.2017
comment
попробуйте изменить componentDidMount на componentWillReceiveProps(nextProps) или попробуйте console.log в this.props в вашем методе рендеринга   -  person azium    schedule 15.11.2017
comment
Поэтому, когда я переместил console.log в метод рендеринга заголовка, я увидел, что состояние на короткое время изменилось на true. Но при перемещении в другой раздел после входа в систему состояние снова возвращается к false. Я начинаю задаваться вопросом, может ли это быть мой объект истории, который сбрасывает мое состояние в исходное состояние.   -  person Calvin    schedule 15.11.2017


Ответы (1)


Спасибо всем за комментарии, вы все классные! Это помогло мне понять, что модуль истории npm, который я использовал для программной навигации в моем создателе действий, по какой-то причине сбрасывал мое состояние redux (если кому-то интересно, вот ссылка на github модуля истории: https://github.com/ReactTraining/history). После удаления модуля из моего приложения состояние redux теперь обновляется и остается обновленным, как и ожидалось.

person Calvin    schedule 16.11.2017