2017-08-25 73 views
2

我正在使用React,我的状态被定义为一个对象数组。 我需要能够改变state.data阵列只在一个特定的元素,例如ID对象1如何使用setState更新对象数组中的对象

我想知道:

  • 什么是正确的方法如何使用setState()在这种情况下。

constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
    data: [{ 
 
     id: 0, 
 
     title: 'Buy a', 
 
     status: 0, // 0 = todo, 1 = done 
 
     }, 
 
     { 
 
     id: 1, 
 
     title: 'Buy b', 
 
     status: 0, 
 
     }, 
 
     { 
 
     id: 2, 
 
     title: 'Buy c', 
 
     status: 0, 
 
     } 
 
    ] 
 
    }; 
 
    this.onTitleChange = this.onTitleChange.bind(this); 
 
} 
 
onTitleChange(id, title) { 
 
    console.log(id, title); 
 
    debugger 
 
}

回答

2

你可以得到做的克隆状态对象使用spread运算符,然后找到对象的索引使用findIndex方法的给定ID的数组修改对象并设置状态。

constructor(props) { 
    super(props); 
    this.state = { 
    data: [{ 
     id: 0, 
     title: 'Buy a', 
     status: 0, // 0 = todo, 1 = done 
     }, 
     { 
     id: 1, 
     title: 'Buy b', 
     status: 0, 
     }, 
     { 
     id: 2, 
     title: 'Buy c', 
     status: 0, 
     } 
    ] 
    }; 
    this.onTitleChange = this.onTitleChange.bind(this); 
} 
onTitleChange(id, title) { 
    var data = [...this.state.data]; 
    var index = data.findIndex(obj => obj.id === id); 
    data[index].title = title; 
    this.setState({data}); 
} 
+2

好的答案。只是想指出@Radex应该谨慎使用'setState':'onTitleChange'函数不应该被调用到组件正在更新的生命周期方法中(例如componentDidUpdate),因为否则它会导致无限循环。预先检查此文档条目https://facebook.github.io/react/docs/state-and-lifecycle.html – Fotis

0

一个简单的解决办法是:

const idx = this.state.data.findIndex(obj => obj === id); 
this.state.data[idx].title = title; 

对于更复杂的成分,我会建议使用Immutable.js List

+0

我需要使用setState,否则组件会在更新时渲染属性 – Radex

0

我会用传播运营商来更新状态。

onTitleChange(id, title) { 
    const { data } = this.state 
    const index = data.findIndex(d => d.id === id) 

    this.setState({ 
    data: [ 
     ...data.slice(0, index), 
     { 
     ...data[index], 
     title: title, 
     }, 
     ...data.slice(index + 1) 
    ] 
    }) 
} 
0

你也可以做这样的事情:

onChange = (id, value, field) => { 
    this.setState((prevState) => ({ 
      data: prevState.data.map((d, index) => { //d = object, index = index in array 
       if (d.id === id) { 
        return { 
         ...d, 
         [field]: value //field/name in object 
        } 
       } 
       return d 
      }) 
     }),() => { 
      console.log("New value of", field, "=", value, "in object with id", id); 
     }); 
} 
0

您还可以修改你

存储在下面的格式

为国家的方式缓解,希望这有助于!

constructor(props) { 
    super(props); 
    this.state = { 
    data: [ 
    0: { 
     id: 0, 
     title: 'Buy a', 
     status: 0, // 0 = todo, 1 = done 
     }, 
    1: { 
     id: 1, 
     title: 'Buy b', 
     status: 0, 
     }, 
    2: { 
     id: 2, 
     title: 'Buy c', 
     status: 0, 
     } 
    ] 
    }; 
    this.onTitleChange = this.onTitleChange.bind(this); 
} 

onTitleChange(id, title) { 
    var newData = [...this.state.data]; 
    newData[id].title = title; 
    this.setState({newData}); 
} 
相关问题