React.js: перезапись setState, а не слияние
Я совершенно новый, чтобы реагировать. Я и в процессе экспериментирования создаю макет стиля макета.
Я визуализирую каждый элемент в DOM, тогда мне нужно перебрать каждый элемент и применить положения x и y на основе предыдущих элементов.
Начальная модель выглядит следующим образом:
[
{
"title": "The Forrest",
"description": "some cool text",
"imgSmallSrc": "/img/img4-small.jpg",
"imgAlt": "Placeholder image",
"tags": [
"Design",
"Mobile",
"Responsive"
],
"date": 1367154709885,
"podStyle": {
"width": 253
}
}
]
(Я только показал один элемент, чтобы все было в порядке).
Как только я закончу цикл и получаю свои данные x и y, я хочу применить это к объекту podStyle. Я вызываю setState со следующими данными:
[
{
"podStyle": {
"x": 0,
"y": 0,
"height": 146,
"width": 253
}
}
]
Это, кажется, удаляет все текущие данные из модели и оставляет меня только с данными podStyle. Я не понимаю, как работает это слияние?
Заранее благодарим за помощь!
Ответы
Ответ 1
Если ваше состояние является объектом:
getInitialState: function() {
return { x: 0, y: 0 };
}
вы можете использовать setState
для установки отдельных клавиш на этом объекте:
this.setState({ x: 1 }); // y still == 0
Реагирует не интеллектуальное слияние вашего состояния; например, это не работает:
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)
[изменить]
Как уже упоминалось @ssorallen, вы можете использовать помощники неизменяемости, чтобы получить эффект, который вам нужен:
var newState = React.addons.update(this.state, {
point: { x: {$set: 10} }
});
this.setState(newState);
Смотрите этот JSFiddle для примера: http://jsfiddle.net/BinaryMuse/HW6w5/
Ответ 2
Слияние нечетное, поэтому this.setState({point})
оставляет (ed: this.state.radius) неповрежденным, но полностью заменяет (ed: this.state.point).
https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-are-merged
Чтобы предложить ответы ES7 + на уже предоставленные ответы, используйте transform-object-rest-spread вместо Object.assign()
:
class MyComponent extends React.Component {
state = {
point: {
x: 0,
y: 0,
},
radius: 10,
}
handleChange = () => {
this.setState({
point: {
// rest operator (...) expands out to:
...this.state.point, // x:0, y:0,
y: 1, // overwrites old y
},
// radius is not overwritten by setState
});
}
render() {
// omitted
}
}
.babelrc(также требует transform-class-properties с этапа предустановки Babel 2)
{
"presets": ["es2015", "stage-2", "react"],
"plugins": ["transform-object-rest-spread"],
}
Ответ 3
Что-то вроде:
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);
Было бы лучше, если бы оно было рекурсивным/глубоким, а не жестким кодированием дерева, но я оставлю это до читателя:)