我有一个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)
这是一张图片,其中我描述了在分配每个动作后的状态:
每当调度一个动作并记录上一个和下一个状态时,它们都是正确的,但我的组件不会得到更新。
我在这里遗漏了什么,或者这真的是一个错误?
答案 0 :(得分:-1)
请测试您的Reducer 。 请保持状态持平 。 使用高阶组件进行身份验证逻辑 。使用重新选择来提高性能。它是一个bug测试你的减少。这应该工作。并且深度嵌套的状态并不好,因为它会使你难以思考和管理。 我的代码如下:
import { combineReducers } from 'redux';
//import the reducers ou want
const authReducer = combineReducers({
loginData: LoginReducer,
permission: permissionReducer
});
export default rootReducer;