发生调度,但商店仅部分更新

Dispatches occur, but store is only partially updated

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

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

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

我找到的文档没有显示是否有必要区别对待 rootReducer 存储和非组合存储。此外,登录流程依赖于相同的函数来分派这两个操作,因此问题一定出在 userReducer 或操作中。

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

Edit2:放置在 userReducer 中的调试器显示分派操作最初确实到达了 'ADD_USER' 和 returns 正确的对象,但它在之后立即分派了几次,并以某种方式重置了介于两者之间的用户状态加载不同的页面。这是正常行为吗?

//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 }
}

我明白了。该项目需要 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);