Redux (with React) Reducer switch 语句不更新状态

Posted

技术标签:

【中文标题】Redux (with React) Reducer switch 语句不更新状态【英文标题】:Redux (with React) Reducer switch statement NOT updating State 【发布时间】: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 【参考方案1】:

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

【讨论】:

以上是关于Redux (with React) Reducer switch 语句不更新状态的主要内容,如果未能解决你的问题,请参考以下文章

[Redux] Generating Containers with connect() from React Redux (FooterLink)

Redux (with React) Reducer switch 语句不更新状态

[Redux] Generating Containers with connect() from React Redux (AddTodo)

[React Native] Reduce Long Import Statements in React Native with Absolute Imports

React Redux with hooks - 身份验证和受保护的路由

React-Native with Redux:API 对象出现在我的 console.log 中,但不在我的视图中