我试图以默认用户为默认状态在获取后将用户信息保存。但是,如果用户状态随UpdateSertate的变化而变化,则默认用户也会更改。我不明白behaivour
- 首先从RESTAPI获取数据
- 在MainComponent上更新用户状态
-
如果用户更改模式上的文本input,则更新用户状态。
const userReducer = (state = {} ,action) => { switch (action.type) { case actionTypes.GETUSERINFOBYUSERNAME_SUCCESS: return { ...state, isFetching: action.isFetching, error: action.error, user: action.user, defaultUser:action.user, open: true }; case actionTypes.UPDATEUSERSTATE: return { ...state, user: action.user } default: console.log("[userReducer]: defalt state"); return state; } }; //ACTIONS export const getUserInfoByUserNameSuccess=(user) => { return {type: actionTypes.GETUSERINFOBYUSERNAME_SUCCESS, isFetching: true, error: null, user: user} } export const updateUserState=(user) => { return {type: actionTypes.UPDATEUSERSTATE, user:user} } //CALLING GETUSERINFO this.props.onGetUserInfoByUserName(val); const mapDispatchToProps = dispatch => { return{ onGetUserInfoByUserName : userName => dispatch(getUserInfoByUserNameFetching(userName)) }; }; //AND CALLING UPDATEUSERSTATE textChangedHandler = (key,value) => { let user = this.props.user; user[key]=value; this.props.onUpdateUserState(user); } const mapDispatchToProps = dispatch => { return{ onUpdateUserState : (user) => dispatch(updateUserState(user)) }; };
这里的问题是,您直接设置了两个独立对象的值以引用同一对象(user
和defaultUser
都设置为引用对象action.user
)。因此,如果您更改一个对象的值,则引用更改会更改第二个对象。
redux不会用新对象替换对象,而是对新值进行浅副本。请参阅下图的示例:
var actionUser = { foo: 1 }
var defaultUser = actionUser
var user = actionUser
user.bar = 2
console.log(actionUser)
// { foo: 1, bar: 2 }
console.log(defaultUser)
// { foo: 1, bar: 2 }
console.log(user)
// { foo: 1, bar: 2 }
要解决此问题,您可以使用Object.assign()
方法将引用分配给新对象。参见下图:
var actionUser = { foo: 1 }
var defaultUser = Object.assign({}, actionUser)
var user = Object.assign({}, actionUser)
user.bar = 2
console.log(actionUser)
// { foo: 1 }
console.log(defaultUser)
// { foo: 1 }
console.log(user)
// { foo: 1, bar: 2 }
因此,每当您将动作的新值分配给任何状态对象时,请使用Object.assign()
。
示例(来自您的代码):
case actionTypes.GETUSERINFOBYUSERNAME_SUCCESS:
return {
...state,
user: Object.assign({}, action.user),
defaultUser: Object.assign({}, action.user),
};
case actionTypes.UPDATEUSERSTATE:
return {
...state,
user: Object.assign({}, action.user),
}