Hãy nghĩ về trạng thái của ứng dụng dưới dạng cơ sở dữ liệu. Tôi đề nghị bạn sử dụng hình dạng trạng thái này:
{
entities: {
// List of normalized posts without any nesting. No matter whether they have all fields or not.
posts: {
'1': {
id: '1',
title: 'Post 1',
},
'2': {
id: '2',
title: 'Post 2',
}
},
},
// Ids of posts, which need to displayed.
posts: ['1', '2'],
// Id of full post.
post: '2',
}
Trước hết, chúng ta đang tạo normalizr
schemas của chúng tôi:
// schemas.js
import { Schema, arrayOf } from 'normalizr';
const POST = new Schema('post');
const POST_ARRAY = arrayOf(POST);
Sau khi phản ứng thành công, chúng tôi được bình thường hóa dữ liệu phản ứng và cử hành động:
// actions.js/sagas.js
function handlePostsResponse(body) {
dispatch({
type: 'FETCH_POSTS',
payload: normalize(body.result, POST_ARRAY),
});
}
function handleFullPostResponse(body) {
dispatch({
type: 'FETCH_FULL_POST',
payload: normalize(body.result, POST),
});
}
trong gia giảm, chúng ta cần tạo entities
giảm, mà sẽ được nghe tất cả các hành động và nếu nó có entities
quan trọng trong việc trả tải, sẽ thêm các đối tượng này sang trạng thái ứng dụng:
// reducers.js
import merge from 'lodash/merge';
function entities(state = {}, action) {
const payload = action.payload;
if (payload && payload.entities) {
return merge({}, state, payload.entities);
}
return state;
}
Ngoài ra chúng tôi cần phải tạo ra tương ứng gia giảm để xử lý FETCH_BOARDS
và FETCH_FULL_BOARD
hành động:
// Posts reducer will be storing only posts ids.
function posts(state = [], action) {
switch (action.type) {
case 'FETCH_POSTS':
// Post id is stored in `result` variable of normalizr output.
return [...state, action.payload.result];
default:
return state;
}
}
// Post reducer will be storing current post id.
// Further, you can replace `state` variable by object and store `isFetching` and other variables.
function post(state = null, action) {
switch (action.type) {
case 'FETCH_FULL_POST':
return action.payload.id;
default:
return state;
}
}
Tôi có một câu hỏi: Liệu 'hợp nhất ({}, state, payload.entities);' biến đổi trạng thái? – Daskus
@Daskus Không, khi chúng ta truyền đối tượng rỗng làm đối số đầu tiên, hàm 'merge' sẽ trả về đối tượng mới. – 1ven
Đây là câu trả lời hay nhất, chúng tôi đã kết thúc chính xác cho phương pháp này. chìa khóa là viết các bộ chọn và bộ lọc tốt. Cũng rất khuyên bạn nên sử dụng JS bất biến ...! – AndrewMcLagan