【问题标题】:Redux (with React) Reducer switch statement NOT updating StateRedux (with React) Reducer switch 语句不更新状态
【发布时间】:2018-04-29 01:33:19
【问题描述】:

正如标题所示,我正在努力使用 reducer 更新我的 Redux 状态。我也在使用 Redux 和 React。在这种情况下,我使用 Redux 状态来保存用户是否使用 JWT 令牌登录的布尔值。我相当确定我的减速器设置正确,因为我可以通过控制台注销默认设置为 false 的初始身份验证状态。但是,当我运行 AUTH_USER 操作告诉减速器将状态更新为已验证 = true 时,没有任何反应。记录 auth 的 redux 状态时,即使在我为 AUTH_USER 运行操作之后,它仍然为 false。由于 console.log 显示在终端中,因此它似乎正确地进入了 reducer 中的 switch 语句。我从头组件的 componentDidMount 生命周期方法中获取控制台日志,该方法呈现在我的 React 应用程序的每个部分。

Reducers 的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;
  }
}

用于登录的 Action Creator (/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();

如果有人能帮助阐明这个问题,我将非常感激!

【问题讨论】:

  • 您说“什么都没有发生”,但您还没有发布任何发生的代码。你在哪里记录它期望状态改变?
  • 明白了,我去补充一下
  • 您能否将您的 index.js 以及您正在使用的位置发布到 &lt;Route&gt;
  • 所有更新,包括相对文件位置!
  • 您所在的州没有 auth 属性。在你的mapStateToProps 中,这个authenticated: state.auth 应该是这个authenticated: state.authenticated

标签: reactjs authentication redux react-redux redux-thunk


【解决方案1】:

感谢大家的cmets,你们都很棒!它帮助我意识到我在动作创建器中用于编程导航的历史 npm 模块出于某种原因正在重置我的 redux 状态(如果有人好奇,这里是历史模块的 github 的链接:https://github.com/ReactTraining/history)。从我的应用程序中删除模块后,redux 状态现在会按预期更新并保持更新。

【讨论】:

    猜你喜欢
    • 2021-01-08
    • 1970-01-01
    • 2019-07-18
    • 2020-04-13
    • 2019-07-28
    • 2017-11-10
    • 2017-08-08
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多