Это звучит как большой прецедентом для метода .map()
Array.
Если предположить, что данные выглядит следующим образом:
var todos = [
{
id: 1,
title: 'Todo 1 Title',
body: 'Todo 1 Body',
date: 1425364758,
comments: [
{
id: 1,
commentorId: 42069,
text: 'Todo 1, Comment 1 Text',
date: 1425364758
},
{
id: 2,
commentorId: 42069,
text: 'Todo 1, Comment 2 Text',
date: 1425364758
},
{
id: 3,
commentorId: 42069,
text: 'Todo 1, Comment 3 Text',
date: 1425364758
}
]
},
{
id: 2,
title: 'Todo 2 Title',
body: 'Todo 2 Body',
date: 1425364758,
comments: [
{
id: 1,
commentorId: 42069,
text: 'Todo 2, Comment 1 Text',
date: 1425364758
}
]
},
{
id: 3,
title: 'Todo 3 Title',
body: 'Todo 3 Body',
date: 1425364758,
comments: [
{
id: 1,
commentorId: 42069,
text: 'Todo 3, Comment 1 Text',
date: 1425364758
},
{
id: 2,
commentorId: 42069,
text: 'Todo 3, Comment 2 Text',
date: 1425364758
}
]
}
];
При обновлении комментарий, вы должны были бы пройти в todoId
и commentId
, чтобы вы знали, что искать. При добавлении комментария, вам нужно только пройти в todoId
, так что вы знаете, какой список дел, чтобы обновить:
const todoReducer = (todos = [], action) => {
switch(action.type) {
case 'ADD_TODO':
return [
action.todo,
...todos
];
case 'ADD_COMMENT':
const { todoId, comment } = action;
// Map through all the todos. Returns a new array of todos, including the todo with a new comment
return todos.map(todo => {
// Look for the todo to add a comment to
if (todo.id === todoId) {
// When the todo to update is found, add a new comment to its `comments` array
todo.comments.push(comment);
}
// Return the todo whether it's been updated or not
return todo;
});
case 'UPDATE_COMMENT':
const { todoId, commentId, commentText } = action;
// Map through all the todos. Returns a new array of todos, including the todo with the updated comment
return todos.map(todo => {
// First find the todo you want
if (todo.id === todoId) {
// Then iterate through its comments
todo.comments.forEach(comment => {
// Find the comment you want to update
if (comment.id === commentId) {
// and update it
comment.text = commentText;
}
});
}
// Return the todo whether it's been updated or not
return todo;
});
default:
return todos;
}
};
export default todoReducer;
Как для полезных нагрузок, вы можете сделать их, что вы хотите, и они будут созданы в ваш создатель действия. Например, вот реализация ADD_TODO
, что дает Todo уникальный идентификатор, метки времени, и добавляет пустой comments
массив перед обжигом действия:
import uuid from 'node-uuid';
const addTodo = ({title, body}) => {
const id = uuid.v4();
const date = new Date().getTime();
return {
type: 'ADD_TODO',
todo: {
id,
title,
body,
date,
comments: []
}
};
};
Вашего ADD_COMMENT
действия создатель может выглядеть примерно так:
import uuid from 'node-uuid';
const addComment = ({todoId, commentorId, commentText}) => {
const id = uuid.v4();
const date = new Date().getTime();
return {
type: 'ADD_COMMENT',
todoId,
comment: {
id,
commentorId,
date,
text: commentText
}
};
};
Это непроверено, но, надеюсь, дает вам представление.
[Updeep] (https://github.com/substantial/updeep) упрощает выполнение обновлений вложенных объектов и массивов; Я бы рекомендовал взглянуть на него. –
http://stackoverflow.com/questions/37980109/react-redux-complex-deep-state-objects duplicate – xiaofan2406
@ xiaofan2406 Я проверил его, но я не могу понять концепцию достаточно хорошо. Если вы не можете привести пример в соответствии с тем, что я представил? Спасибо –