无法在不覆盖或丢失状态中的其他项目的情况下更新 Redux 中的对象
Can't update an object in Redux without overwriting it or losing other items in state
简要概述..
我的状态是这样的:
isAuthenticated: true
user: {
avatar: 'avatar.jpg'
name: 'John Doe'
username: 'johndoe'
id: '6dHjStye45fds885'
}
我试图在减速器中仅更新 avatar
属性 和 Redux
,但我尝试过的任何东西都没有按预期工作。我一定做错了,但我只是不知道是什么。我已经尽可能多地阅读了有关该主题的内容,但似乎没有任何内容可以正常工作。
如果我这样做:
return {
...state,
user: {
...state.user,
avatar: action.payload
}
};
它完全消除了 isAuthenticated
并仅用化身替换了 user
对象,破坏了之前状态中的所有其他内容。我想我正在用 avatar: action.payload
?
清除传播运算符
如果这样做:
return {
...state,
...state.user,
avatar: action.payload
};
它也清除了isAuthenticated
,但是这次将所有用户数据(包括新的avatar
)放在状态的顶层(不再在对象中)。
有人可以告诉我哪里出错了吗?
编辑 添加相关文件
authReducer.js(截断删除不相关的代码)
import isEmpty from '../../functions/isEmpty';
import { SET_CURRENT_USER, SET_AVATAR } from '../actionTypes';
const initialState = {
isAuthenticated: false,
user: {}
};
export default function(state = initialState, action) {
switch (action.type) {
case SET_CURRENT_USER:
return {
...state,
isAuthenticated: !isEmpty(action.payload),
user: action.payload
};
case SET_AVATAR:
return {
...state,
user: {
...state,
avatar: action.payload
}
};
default:
return state;
}
}
rootReducer.js
import { combineReducers } from 'redux';
import authReducer from './reducers/authReducer';
import errorReducer from './reducers/errorReducer';
export default combineReducers({
auth: authReducer,
errors: errorReducer
});
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './rootReducer';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
您需要 return 个 authReducer.js 中的新对象
var newUserObject = Object.assign({}, state.user, {
avatar: action.payload.avatar // or some other fields
})
return Object.assign({}, state, {user: newUserObject})
在 store.js 中,您似乎将初始状态作为空对象传递。这可能就是为什么当您使用展开运算符时所有内容都会被清除。
尝试从声明它的任何地方导入默认状态,并创建一个具有所有默认状态的对象以在 createStore
.
中使用
import { initialState as authInitialState } from './authReducer.js'
import { initialState as errorInitialState } from './errorRerducer.js'
const initialState = { ...authInitialState, ...errorInitialState };
更改 authReducer.js 文件中的代码,
由此
case SET_AVATAR:
return {
...state,
user: {
...state,
avatar: action.payload
}
};
至此
case SET_AVATAR:
return {
...state,
user: {
...state.user,
avatar: action.payload
}
};
或这个
case SET_AVATAR:
return {
isAuthenticated: state.isAuthenticated,
user: {
...state.user,
avatar: action.payload
},
};
简要概述..
我的状态是这样的:
isAuthenticated: true
user: {
avatar: 'avatar.jpg'
name: 'John Doe'
username: 'johndoe'
id: '6dHjStye45fds885'
}
我试图在减速器中仅更新 avatar
属性 和 Redux
,但我尝试过的任何东西都没有按预期工作。我一定做错了,但我只是不知道是什么。我已经尽可能多地阅读了有关该主题的内容,但似乎没有任何内容可以正常工作。
如果我这样做:
return {
...state,
user: {
...state.user,
avatar: action.payload
}
};
它完全消除了 isAuthenticated
并仅用化身替换了 user
对象,破坏了之前状态中的所有其他内容。我想我正在用 avatar: action.payload
?
如果这样做:
return {
...state,
...state.user,
avatar: action.payload
};
它也清除了isAuthenticated
,但是这次将所有用户数据(包括新的avatar
)放在状态的顶层(不再在对象中)。
有人可以告诉我哪里出错了吗?
编辑 添加相关文件
authReducer.js(截断删除不相关的代码)
import isEmpty from '../../functions/isEmpty';
import { SET_CURRENT_USER, SET_AVATAR } from '../actionTypes';
const initialState = {
isAuthenticated: false,
user: {}
};
export default function(state = initialState, action) {
switch (action.type) {
case SET_CURRENT_USER:
return {
...state,
isAuthenticated: !isEmpty(action.payload),
user: action.payload
};
case SET_AVATAR:
return {
...state,
user: {
...state,
avatar: action.payload
}
};
default:
return state;
}
}
rootReducer.js
import { combineReducers } from 'redux';
import authReducer from './reducers/authReducer';
import errorReducer from './reducers/errorReducer';
export default combineReducers({
auth: authReducer,
errors: errorReducer
});
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './rootReducer';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
您需要 return 个 authReducer.js 中的新对象
var newUserObject = Object.assign({}, state.user, {
avatar: action.payload.avatar // or some other fields
})
return Object.assign({}, state, {user: newUserObject})
在 store.js 中,您似乎将初始状态作为空对象传递。这可能就是为什么当您使用展开运算符时所有内容都会被清除。
尝试从声明它的任何地方导入默认状态,并创建一个具有所有默认状态的对象以在 createStore
.
import { initialState as authInitialState } from './authReducer.js'
import { initialState as errorInitialState } from './errorRerducer.js'
const initialState = { ...authInitialState, ...errorInitialState };
更改 authReducer.js 文件中的代码,
由此
case SET_AVATAR:
return {
...state,
user: {
...state,
avatar: action.payload
}
};
至此
case SET_AVATAR:
return {
...state,
user: {
...state.user,
avatar: action.payload
}
};
或这个
case SET_AVATAR:
return {
isAuthenticated: state.isAuthenticated,
user: {
...state.user,
avatar: action.payload
},
};