使用combineReducers后,组件停止更新

时间:2016-06-14 21:45:55

标签: javascript reactjs redux react-redux

目前的行为是什么?

我有一个Header组件,在获取登录数据后应该更新。它会检查用户的姓名并显示欢迎信息。

在不使用combineReducers的情况下创建商店时,仅使用我创建的loginReducer一切正常,状态会更新,然后组件也会更新。但是,当使用combineReducers时,即使我在其中使用相同的单个reducer,该组件也会停止更新。我还使用记录器中间件来显示状态变化,状态似乎正在正确更新。

代码示例:

这有效:

请注意,我此处仅显示相关文件部分。

index.js

const loggerMiddleware = createLogger();

// Here I'm creating the store with a single reducer function
const store = createStore(loginReducer, applyMiddleware(thunkMiddleware, loggerMiddleware));

const router = createRouter();

ReactDOM.render(<Provider store={store}>
        { router }
    </Provider>,
    document.getElementById('root')
);

loginReducer.js

// Please notice that here I'm not mutating state in any way
// I'm always returning a new state as recommended by the docs
const ACTION_HANDLERS = {
  [REQUEST_LOGIN]: (state, action) => {
    return ({ ...state, username: action.payload.username, authHeader: 'Basic ' + base64Encode(action.payload.username + ':' + md5(action.payload.password))});
  },
  [RECEIVE_LOGIN]: (state, action) => {
    return ({ ...state, resources: action.payload.resources, isCashier: action.payload.isCashier });
  },
  [LOGOUT]: (state) => {
    return ({ ...state, username: null, resources: {}, authHeader: null, isCashier: null });
  }
}

const initialState = { isCashier: null, resources: {}, username: null };
export default function loginReducer (state = initialState, action) {
  const handler = ACTION_HANDLERS[action.type]

  return handler ? handler(state, action) : state
}

export default loginReducer;

LoginContainer.js

const mapActionCreators = {
  doLogin,
  doLogout
}

const mapStateToProps = (state) => ({
  resources: state.resources,
  username: state.username
})

export default connect(mapStateToProps, mapActionCreators)(Login)

这不起作用:

这是一个不起作用的版本,我所做的唯一改变是: *我现在将loginReducer包裹在combineReducers内 *我更改了mapStateToProps函数,以便从状态中的嵌套login对象中获取这些属性

index.js

const rootReducer = combineReducers({
    login: loginReducer
});

const loggerMiddleware = createLogger();

// Now I'm not using the raw `loginReducer` anymore
const store = createStore(rootReducer, applyMiddleware(thunkMiddleware, loggerMiddleware));

const router = createRouter();

ReactDOM.render(<Provider store={store}>
        { router }
    </Provider>,
    document.getElementById('root')
);

loginReducer.js - &gt;这保持与上面相同

LoginContainer.js

const mapActionCreators = {
  doLogin,
  doLogout
}

// Here I'm getting properties from `state.login` instead of `state` now due to the use of combineReducers
const mapStateToProps = (state) => ({
  resources: state.login.resources,
  username: state.login.username
})

export default connect(mapStateToProps, mapActionCreators)(Login)

这是一张图片,其中我描述了在分配每个动作后的状态:

correct

每当调度一个动作并记录上一个和下一个状态时,它们都是正确的,但我的组件不会得到更新。

我在这里遗漏了什么,或者这真的是一个错误?

1 个答案:

答案 0 :(得分:-1)

请测试您的Reducer 请保持状态持平 使用高阶组件进行身份验证逻辑 。使用重新选择来提高性能。它是一个bug测试你的减少。这应该工作。并且深度嵌套的状态并不好,因为它会使你难以思考和管理。 我的代码如下:

import { combineReducers } from 'redux';
//import the reducers ou want

const authReducer = combineReducers({
  loginData: LoginReducer,
  permission: permissionReducer
});

export default rootReducer;

检查此http://redux.js.org/docs/recipes/WritingTests.html