【问题标题】:Dispatches occur, but store is only partially updated发生调度,但商店仅部分更新
【发布时间】:2020-08-23 07:59:36
【问题描述】:

我正在尝试更新我的登录流程的用户状态。用户是 rootReducer 的一部分。 Session 也是,但是那个 state 的 reducer 属于 redux-react-session 库。

我的登录流程是:用户访问页面,输入用户名和密码。用户按下登录表单按钮。提交时,会话调用服务器并登录用户。在登录过程中,用户状态的调度运行。

但是运行之后,用户状态还是之前的样子。登录显然成功。所以会话状态是用新数据填充的,而用户状态不是。整个日志表明 userReducer 被调用,并且它返回的状态符合预期。是否有一些特殊的方法可以将 userReducer 连接到商店,或者更新它?以下代码失败。

我发现的文档没有显示是否有必要将 rootReducer 存储与非组合存储区别对待。此外,登录流程依赖于相同的函数来调度这两个操作,因此问题必须在 userReducer 或操作中的某个地方。

编辑:提供的代码在遇到 userReducer 时会变为默认情况。我通过设置默认大小写来提供不同的电子邮件值来确认这一点。为什么 userReducer 不接受 UserActions#userAdd 返回的动作类型?甚至在什么时候调用了 userReducer?

Edit2:放置在 userReducer 中的调试器显示调度操作最初确实到达“ADD_USER”并返回正确的对象,但它在之后立即进行了多次调度,并以某种方式在加载不同页面之间重置用户状态。这是正常行为吗?

//rootReducer.js
const reducers = {
  user: userReducer,
  session: sessionReducer
};

const rootReducer = combineReducers(reducers);




//userReducer.js
function userReducer(state = { email: '', projects: [] }, action) {
  switch (action.type) {
    case 'ADD_USER':
      return Object.assign({}, state, action.user);
    case 'LOGOUT_USER':
       return {email: '', projects: [] };
       case 'EDIT_USER':
         return { email: '', projects: [] };
    case 'DELETE_USER':
      return { email: '', projects: [] };

    default:
      return state;
  }
}

export default userReducer;




//LoginContainer.js
//this component calls the failing dispatch
//dispatch is default provided dispatch from connect function
import { connect } from 'react-redux';
import * as sessionActions from '../actions/SessionActions';
import * as userActions from '../actions/UserActions';

...
onSubmit = (e, history) => {
    e.preventDefault();

    this.props.dispatch(sessionActions.login(this.state, history, this.props.dispatch, userActions.addUser))

    //addUser({email: this.state.email, projects: []});
  }
...
export default connect(null)(LoginContainer);





//SessionActions.js
//failing code lives here:
//dispatch(addUser(json)); seems to fail somehow
//even though flow is basically the same as session
export const login = (state, history, dispatch, addUser) => {
  return () => {
    return sessionApi.login(state).then(response => response.json()).then(json => {
      sessionService.saveSession({ json })
      .then(() => {

        sessionService.saveUser(json)
        .then(() => {
          if (json.email) {
            console.log(state);
            console.log(json);

            dispatch(addUser(json));
            localStorage.setItem("loggedIn", true);
            localStorage.setItem("user", JSON.stringify(json.email));
            history.push('/');
            //history.go(0);
          }
        }).catch(err => console.error(err));
      }).catch(err => console.error(err));
    });
  };
};




//UserActions.js
export const addUser = (user) => {
  console.log(user);
  return {type: 'ADD_USER', user }
}

【问题讨论】:

  • ADD_USER 的操作负载是什么?你能验证吗?猜测是动作负载是空的,因此没有发生任何变化
  • 有一个名为 user 的操作,结构为 user: {email: user.email}。

标签: javascript react-redux redux-thunk


【解决方案1】:

我想通了。该项目需要 redux-persist 以便状态数据从一页重新水化到下一页。会话状态对此功能有自己的处理方式。

下面是使用 combineReducers 和 redux-react-session 和 redux-thunk 实现的代码。我仍在努力完善合并级别。

$ npm install redux-persist

//configureStore.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import { sessionService } from 'redux-react-session';
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web

import rootReducer from './rootReducer';

const persistConfig = {
  key: 'root',
  storage,
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export let store = createStore(persistedReducer, applyMiddleware(thunk));
sessionService.initSessionService(store);
export let persistor = persistStore(store);

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多