在 React 中切换嵌套状态对象
Toggling nested state object in React
我有一个包含对象数组的状态对象:
this.state = {
feeling: [
{ name: 'alert', status: false },
{ name: 'calm', status: false },
{ name: 'creative', status: false },
{ name: 'productive', status: false },
{ name: 'relaxed', status: false },
{ name: 'sleepy', status: false },
{ name: 'uplifted', status: false }
]
}
我想在点击事件中将布尔值 status
从 true 切换为 false。我将此函数构建为点击处理程序,但它没有将事件连接到状态更改:
buttonToggle = (event) => {
event.persist();
const value = !event.target.value
this.setState( prevState => ({
status: !prevState.status
}))
}
我很难理解嵌套 React 状态更改的控制流,以及活动事件如何从处理程序跳转到状态对象,反之亦然。
整个组件:
export default class StatePractice extends React.Component {
constructor() {
super();
this.state = {
feeling: [
{ name: 'alert', status: false },
{ name: 'calm', status: false },
{ name: 'creative', status: false },
{ name: 'productive', status: false },
{ name: 'relaxed', status: false },
{ name: 'sleepy', status: false },
{ name: 'uplifted', status: false }
]
}
}
buttonToggle = (event) => {
event.persist();
const value = !event.target.value
this.setState( prevState => ({
status: !prevState.status
}))
}
render() {
return (
<div>
{ this.state.feeling.map(
(stateObj, index) => {
return <button
key={ index }
onClick={ this.buttonToggle }
value={ stateObj.status } >
{ stateObj.status.toString() }
</button>
}
)
}
</div>
)
}
}
为了解决您的问题,您应该首先将要修改的元素的索引发送到您的切换函数:
onClick = {this.buttonToggle(index)}
然后调整函数以接收索引和事件。
现在,要修改您的状态数组,复制它,更改您要查找的值,然后将其放回您的状态:
buttonToggle = index => event => {
event.persist();
const feeling = [...this.state.feeling]; //Copy your array
feeling[index] = !feeling[index];
this.setState({ feeling });
}
您也可以使用 slice
来复制您的数组,甚至直接发送一个 mapped
数组,其中只有一个值被更改。
更新反应状态对象中的嵌套对象很棘手。您必须从临时变量中的状态获取整个对象,更新该变量中的值,然后用更新后的变量替换状态。
为此,您的 buttonToggle 函数需要知道按下了哪个按钮。
return <button
key={ index }
onClick={ (event) => this.buttonToggle(event, stateObj.name) }
value={ stateObj.status } >
{ stateObj.status.toString() }
</button>
您的 buttonToggle 函数可能如下所示
buttonToggle = (event, name) => {
event.persist();
let { feeling } = this.state;
let newFeeling = [];
for (let index in feeling) {
let feel = feeling[index];
if (feel.name == name) {
feel = {name: feel.name, status: !feel.status};
}
newFeeling.push(feel);
}
this.setState({
feeling: newFeeling,
});
}
Here's 一个有效的 JSFiddle。
或者,如果你不需要为每个感觉存储比 "name" 和 "status" 更多的数据,你可以像这样重写你的组件状态:
feeling: {
alert: false,
calm: false,
creative: false,
etc...
}
和 buttonToggle:
buttonToggle = (event, name) => {
event.persist();
let { feeling } = this.state;
feeling[name] = !feeling[name];
this.setState({
feeling
});
}
我认为您需要在获取事件时更新整个数组。最好不要改变现有状态。我会推荐以下代码
export default class StatePractice extends React.Component {
constructor() {
super();
this.state = {
feeling: [
{ name: "alert", status: false },
{ name: "calm", status: false },
{ name: "creative", status: false },
{ name: "productive", status: false },
{ name: "relaxed", status: false },
{ name: "sleepy", status: false },
{ name: "uplifted", status: false },
],
};
}
buttonToggle = (index, value) => (event) => {
event.persist();
const toUpdate = { ...this.state.feeling[index], status: !value };
const feeling = [...this.state.feeling];
feeling.splice(index, 1, toUpdate);
this.setState({
feeling,
});
};
render() {
return (
<div>
{this.state.feeling.map((stateObj, index) => {
return (
<button
key={index}
onClick={this.buttonToggle(index, stateObj.status)}
value={stateObj.status}
>
{stateObj.status.toString()}
</button>
);
})}
</div>
);
}
}
我有一个包含对象数组的状态对象:
this.state = {
feeling: [
{ name: 'alert', status: false },
{ name: 'calm', status: false },
{ name: 'creative', status: false },
{ name: 'productive', status: false },
{ name: 'relaxed', status: false },
{ name: 'sleepy', status: false },
{ name: 'uplifted', status: false }
]
}
我想在点击事件中将布尔值 status
从 true 切换为 false。我将此函数构建为点击处理程序,但它没有将事件连接到状态更改:
buttonToggle = (event) => {
event.persist();
const value = !event.target.value
this.setState( prevState => ({
status: !prevState.status
}))
}
我很难理解嵌套 React 状态更改的控制流,以及活动事件如何从处理程序跳转到状态对象,反之亦然。
整个组件:
export default class StatePractice extends React.Component {
constructor() {
super();
this.state = {
feeling: [
{ name: 'alert', status: false },
{ name: 'calm', status: false },
{ name: 'creative', status: false },
{ name: 'productive', status: false },
{ name: 'relaxed', status: false },
{ name: 'sleepy', status: false },
{ name: 'uplifted', status: false }
]
}
}
buttonToggle = (event) => {
event.persist();
const value = !event.target.value
this.setState( prevState => ({
status: !prevState.status
}))
}
render() {
return (
<div>
{ this.state.feeling.map(
(stateObj, index) => {
return <button
key={ index }
onClick={ this.buttonToggle }
value={ stateObj.status } >
{ stateObj.status.toString() }
</button>
}
)
}
</div>
)
}
}
为了解决您的问题,您应该首先将要修改的元素的索引发送到您的切换函数:
onClick = {this.buttonToggle(index)}
然后调整函数以接收索引和事件。
现在,要修改您的状态数组,复制它,更改您要查找的值,然后将其放回您的状态:
buttonToggle = index => event => {
event.persist();
const feeling = [...this.state.feeling]; //Copy your array
feeling[index] = !feeling[index];
this.setState({ feeling });
}
您也可以使用 slice
来复制您的数组,甚至直接发送一个 mapped
数组,其中只有一个值被更改。
更新反应状态对象中的嵌套对象很棘手。您必须从临时变量中的状态获取整个对象,更新该变量中的值,然后用更新后的变量替换状态。 为此,您的 buttonToggle 函数需要知道按下了哪个按钮。
return <button
key={ index }
onClick={ (event) => this.buttonToggle(event, stateObj.name) }
value={ stateObj.status } >
{ stateObj.status.toString() }
</button>
您的 buttonToggle 函数可能如下所示
buttonToggle = (event, name) => {
event.persist();
let { feeling } = this.state;
let newFeeling = [];
for (let index in feeling) {
let feel = feeling[index];
if (feel.name == name) {
feel = {name: feel.name, status: !feel.status};
}
newFeeling.push(feel);
}
this.setState({
feeling: newFeeling,
});
}
Here's 一个有效的 JSFiddle。
或者,如果你不需要为每个感觉存储比 "name" 和 "status" 更多的数据,你可以像这样重写你的组件状态:
feeling: {
alert: false,
calm: false,
creative: false,
etc...
}
和 buttonToggle:
buttonToggle = (event, name) => {
event.persist();
let { feeling } = this.state;
feeling[name] = !feeling[name];
this.setState({
feeling
});
}
我认为您需要在获取事件时更新整个数组。最好不要改变现有状态。我会推荐以下代码
export default class StatePractice extends React.Component {
constructor() {
super();
this.state = {
feeling: [
{ name: "alert", status: false },
{ name: "calm", status: false },
{ name: "creative", status: false },
{ name: "productive", status: false },
{ name: "relaxed", status: false },
{ name: "sleepy", status: false },
{ name: "uplifted", status: false },
],
};
}
buttonToggle = (index, value) => (event) => {
event.persist();
const toUpdate = { ...this.state.feeling[index], status: !value };
const feeling = [...this.state.feeling];
feeling.splice(index, 1, toUpdate);
this.setState({
feeling,
});
};
render() {
return (
<div>
{this.state.feeling.map((stateObj, index) => {
return (
<button
key={index}
onClick={this.buttonToggle(index, stateObj.status)}
value={stateObj.status}
>
{stateObj.status.toString()}
</button>
);
})}
</div>
);
}
}