Pensa allo stato dell'app come a un database. Vi suggerisco di usare questa forma di stato:
{
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',
}
Prima di tutto, stiamo creando le nostre normalizr
schemi:
// schemas.js
import { Schema, arrayOf } from 'normalizr';
const POST = new Schema('post');
const POST_ARRAY = arrayOf(POST);
dopo la risposta di successo, stiamo normalizzando i dati di risposta e dispacciamento l'azione:
// 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),
});
}
Nei riduttori, è necessario creare il riduttore entities
, che ascolterà tutte le azioni e se ha la chiave entities
in pagamento carico, aggiungerebbe questa entità allo Stato app:
// 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;
}
Inoltre abbiamo bisogno di creare corrispondenti riduttori per gestire FETCH_BOARDS
e FETCH_FULL_BOARD
azioni:
// 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;
}
}
Ho una domanda: 'Unisci ({}, stato, payload.entities);' modifica lo stato? – Daskus
@Daskus No, dato che stiamo passando l'oggetto vuoto come primo argomento, la funzione 'merge' restituirà un nuovo oggetto. – 1ven
Questa è di gran lunga la migliore risposta, abbiamo finito per andare esattamente per questo approccio. la chiave sta nello scrivere buoni selettori e filtri. Raccomandiamo anche l'uso di Immutable JS ...! – AndrewMcLagan