我有一个接收对象数组的要求。我必须检查接收到的对象数组是否已经存在于商店中。如果是,那么我想用旧对象更新新对象,否则我想将新元素添加到存储中。
const initialState = {
....
....
UserChangedData : {
....
....
changedData: []
}
}
export default function (state = initialState, action) {
switch(action.type) {
....
....
....
case SET_USER_BUCKET_LIST_DATA:
// if there is no userChangedData this condition will run initially
if (state.UserChangedData.changedData.length === 0) {
return {
...state,
UserChangedData: {
...state.UserChangedData,
changedData: [...action.payload]
}
};
}
// check if the user item already exists update them. if user item doesn't exists then add
// item to UserChangedData's changedData array with existing data. to check if the item
// exists or not we can use id.
// the object which I receive will be an array of object(s)
// scenario 1 Initial data.
// [{id:1 , name: "john", gender: "Male"}, {id:2 , name: "peter", gender: "Male"}, {id:3 ,
// name: "Natalie", gender: "Female"}, {id:4 , name: "Nicole", gender:"Female"}]
// scenario 2 : user edited one object with id 1 so update the whole object where the inital
// changedData
// example data : [{id:1 , name: "Logan", gender: "Male"}]
// scenario 3: user edited id: 1 and added a new object with id: 8 so update previous id: 1
// with new id: 1 object data and also add new object id: 8 data to changedData array.
// id: 8
// example data: [{id:1 , name: "Jane", gender: "Female"}, {id:8 , name: "Jane",
// gender:"Female"}
我已经尝试了许多逻辑,但没有一个奏效,任何人都可以向我建议上述情况的逻辑。
答案 0 :(得分:1)
据我了解,您想根据其ID值将state.UserChangedData.changedData合并为action.payload。
您可以使用以下reducer实现您想要的:
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case SET_USER_BUCKET_LIST_DATA:
let updatedChangeData = Object.values(
[]
.concat(state.UserChangedData.changedData, action.payload)
.reduce(
(r, c) => ((r[c.id] = Object.assign(r[c.id] || {}, c)), r),
{}
)
);
return {
...state,
UserChangedData: {
...state.UserChangedData,
changedData: updatedChangeData
}
};
default:
return state;
}
};
这个想法来自这篇文章:
How to merge and replace objects from two arrays based on a key in javascript?
以下是完整的代码,可在独立的节点应用程序中使用它:
const redux = require("redux");
const createStore = redux.createStore;
const SET_USER_BUCKET_LIST_DATA = "SET_USER_BUCKET_LIST_DATA";
const initialState = {
UserChangedData: {
changedData: []
}
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case SET_USER_BUCKET_LIST_DATA:
let updatedChangeData = Object.values(
[]
.concat(state.UserChangedData.changedData, action.payload)
.reduce(
(r, c) => ((r[c.id] = Object.assign(r[c.id] || {}, c)), r),
{}
)
);
return {
...state,
UserChangedData: {
...state.UserChangedData,
changedData: updatedChangeData
}
};
default:
return state;
}
};
const store = createStore(rootReducer);
store.subscribe(() => {
console.log("[Subscription]", store.getState().UserChangedData.changedData);
});
store.dispatch({
type: SET_USER_BUCKET_LIST_DATA,
payload: [{ id: 1, title: "A" }]
});
store.dispatch({
type: SET_USER_BUCKET_LIST_DATA,
payload: [{ id: 2, title: "B" }]
});
store.dispatch({
type: SET_USER_BUCKET_LIST_DATA,
payload: [{ id: 1, title: "AA" }]
});
答案 1 :(得分:0)
查看Redux文档中的Immutable Update Patterns。
您的情况:
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
<!-- modify below line like below -->
android:padding="5dp"
/>
始终是数组state.UserChangedData.changedData
中,您应该创建新变量case SET_USER_BUCKET_LIST_DATA:
let newStateChangedData = [...state.UserChangedData.changedData]
中的所有项目,并为每个项目查找action.payload
(如果存在)
state.UserChangedData.changedData
中添加项目)newStateChangedData
中的更新项)对其进行更新newStateChangedData
不应该存在):if