javascript - react helmet seo
React.js: sobrescritura de estado, no fusiĆ³n (3)
Soy bastante nuevo en reaccionar.js y estoy en el proceso de experimentar construyendo un diseño de estilo de mampostería.
Presto cada elemento al DOM, luego tengo que recorrer cada elemento y aplicar las posiciones xey en función de los elementos anteriores.
El modelo inicial se ve así:
[
{
"title": "The Forrest",
"description": "some cool text",
"imgSmallSrc": "/img/img4-small.jpg",
"imgAlt": "Placeholder image",
"tags": [
"Design",
"Mobile",
"Responsive"
],
"date": 1367154709885,
"podStyle": {
"width": 253
}
}
]
(Solo he mostrado un elemento para mantener las cosas cortas).
Una vez que complete el ciclo y tenga mis datos xey, quiero aplicar esto al objeto podStyle. Llamo a setState con los siguientes datos:
[
{
"podStyle": {
"x": 0,
"y": 0,
"height": 146,
"width": 253
}
}
]
Esto parece eliminar todos los datos actuales del modelo y me deja solo con los datos de podStyle. ¿Estoy entendiendo mal cómo funciona esta fusión?
¡Gracias de antemano por cualquier ayuda!
La fusión es superficial, por lo que
this.setState({point})
deja (ed: this.state.radius) intacto, pero reemplaza completamente (ed: this.state.point).https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-are-merged
Ofrecer una perspectiva de ES7 + sobre las respuestas ya dadas, utilizando transform-object-rest-spread lugar de Object.assign()
:
class MyComponent extends React.Component {
state = {
point: {
x: 0,
y: 0,
},
radius: 10,
}
handleChange = () => {
this.setState((prevState, props) => ({
point: {
// rest operator (...) expands out to:
...prevState.point, // x:0, y:0,
y: 1, // overwrites old y
},
// radius is not overwritten by setState
}));
}
render() {
// omitted
}
}
.babelrc (también requiere transform-class-properties de transform-class-properties desde la etapa preestablecida de babel 2)
{
"presets": ["es2015", "stage-2", "react"],
"plugins": ["transform-object-rest-spread"],
}
Actualizado 2018-04-22
Como @sheljohn señala (¡gracias!), Refiriéndose a this.state
dentro de setState
no es confiable:
Como
this.props
ythis.state
se pueden actualizar de forma asincrónica, no debe confiar en sus valores para calcular el siguiente estado....
Para solucionarlo, use una segunda forma de
setState()
que acepte una función en lugar de un objeto. Esa función recibirá el estado anterior como primer argumento, y los puntales en el momento en que se aplica la actualización como el segundo argumentohttps://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
Algo como:
getInitialState: function() {
return {
something: { x: 0, y: 0 },
blah: 10
};
}
var state = Object.assign(this.state, {
something: Object.assign(this.state.something, { y: 50 }),
});
this.setState(state);
Sería mejor si fuera recursivo / profundo en lugar de difícil de codificar el árbol, pero lo dejaré en manos del lector :)
Si su estado es un objeto:
getInitialState: function() {
return { x: 0, y: 0 };
}
puede usar setState
para establecer claves individuales en ese objeto:
this.setState({ x: 1 }); // y still == 0
Reaccionar no hace una fusión inteligente de tu estado; por ejemplo, esto no funciona:
getInitialState: function() {
return {
point: { x: 0, y: 0 },
radius: 10
};
}
this.setState({point: {x: 1}});
// state is now == {point: {x: 1}, radius: 10} (point.y is gone)
[Editar]
Como mencionó @ssorallen, puedes usar los ayudantes de inmutabilidad para obtener el efecto que buscas:
var newState = React.addons.update(this.state, {
point: { x: {$set: 10} }
});
this.setState(newState);
Vea este JSFiddle para un ejemplo: http://jsfiddle.net/BinaryMuse/HW6w5/