javascript - react - Actualización de datos anidados en la tienda redux
redux js (2)
¿Cuál es la mejor / correcta forma de actualizar una matriz anidada de datos en una tienda usando redux?
Mi tienda se ve así:
{
items:{
1: {
id: 1,
key: "value",
links: [
{
id: 10001
data: "some more stuff"
},
...
]
},
...
}
}
Tengo un par de acciones asincrónicas que actualizan el objeto de
items
completos
items
pero tengo otro par de acciones que quiero actualizar una matriz de
links
específica.
Mi reductor actualmente se ve así, pero no estoy seguro de si este es el enfoque correcto:
switch (action.type) {
case RESOURCE_TYPE_LINK_ADD_SUCCESS:
// TODO: check whether the following is acceptable or should we create a new one?
state.items[action.resourceTypeId].isSourceOf.push(action.resourceTypeLink);
return Object.assign({}, state, {
items: state.items,
});
}
El
ayudante de inmutabilidad
update()
React es una forma conveniente de crear una versión actualizada de un objeto JavaScript antiguo sin mutarlo.
Le da el objeto de origen para actualizar y un objeto que describe las rutas a las piezas que deben actualizarse y los cambios que deben realizarse.
por ejemplo, si una acción tenía propiedades de
id
y
link
y desea enviar el
link
a una matriz de enlaces en un elemento marcado con la
id
:
var update = require(''react/lib/update'')
// ...
return update(state, {
items: {
[action.id]: {
links: {$push: action.link}
}
}
})
(El ejemplo usa un nombre de propiedad calculada de ES6 para
action.id
)
La respuesta de Jonny es correcta (¡nunca mutes el estado que te dieron!), Pero quería agregarle otro punto. Si todos sus objetos tienen ID, generalmente es una mala idea mantener la forma de estado anidada.
Esta:
{
items: {
1: {
id: 1,
links: [{
id: 10001
}]
}
}
}
Es una forma que es difícil de actualizar.
¡No tiene por qué ser así! En su lugar, puede almacenarlo así:
{
items: {
1: {
id: 1,
links: [10001]
}
},
links: {
10001: {
id: 10001
}
}
}
Esto es mucho más fácil de actualizar porque solo hay una copia canónica de cualquier entidad.
Si necesita permitir que el usuario "edite un enlace", solo hay un lugar donde debe actualizarse, y es completamente independiente de los
items
o cualquier otra cosa que se refiera a los
links
.
Para obtener sus respuestas API en tal forma, puede usar normalizr . Una vez que sus entidades dentro de las acciones del servidor estén normalizadas, puede escribir un reductor simple que las fusione con el estado actual:
import merge from ''lodash/object/merge'';
function entities(state = { items: {}, links: {} }, action) {
if (action.response && action.response.entities) {
return merge({}, state, action.response.entities);
}
return state;
}
Vea el ejemplo del
real-world
Redux para una demostración de dicho enfoque.