在下面的反应代码中我试图通过更新字典来更改按钮颜色。不幸的是,除非我强行撤回,否则它无法正常工作。
const jsonFromDatabase = [{ "id": 1, "name": "Ka" },
{ "id": 2, "name": "Erd" }];
const json = [{ "id": 2, "name": "Ka" },
{ "id": 3, "name": "Erd" }];
class ControllableButton extends React.Component {
constructor() {
super();
this.state = {
color_black: true,
datasetForDisplay: json,
datasetForStorage: jsonFromDatabase
}
}
onClickGroupToUpdate = (cell, row, rowIndex) => {
let toAdd = { "id": row.id, "name": row.name }
this.setState((prevState, props) => {
datasetForStorage: prevState.datasetForStorage.push(toAdd)
})
console.log("updated the database")
console.log(this.state.datasetForStorage)
// this.forceUpdate()
}
onClickGroupSelected = (cell, row, rowIndex) => {
}
// cellButton should be modified each time of click
cellButton = (cell, row, enumObject, rowIndex) => {
let theButton
let inDB = false
console.log(row)
for (var group in this.state.datasetForStorage) {
if (this.state.datasetForStorage[group].id == row.id) {
inDB = true
}
}
if (inDB) {
theButton = <button style={{ backgroundColor: "blue" }}
type="button"
onClick={() => this.onClickGroupSelected(cell, row, rowIndex)}>
In database
</button>
console.log('already in database' + row.id)
} else {
theButton = <button style={{ backgroundColor: "red" }}
type="button"
onClick={() => this.onClickGroupToUpdate(cell, row, rowIndex)}>
Update database
</button>
console.log('not in database' + row.id)
}
return theButton
}
render() {
return (
<BootstrapTable data={this.state.datasetForDisplay} >
<TableHeaderColumn isKey dataField='id' width='100'>ID</TableHeaderColumn>
<TableHeaderColumn dataField='name' width='300'>Group Name</TableHeaderColumn>
<TableHeaderColumn dataField='button' width='100' dataFormat={this.cellButton}>Generate Group Page</TableHeaderColumn>
</BootstrapTable>
);
}
}
ReactDOM.render(<ControllableButton />, document.getElementById('app'));
每次点击更新组后,上面的代码都不会重新渲染,除非我强制更新。你能帮我弄清楚我在这里做错了吗?
答案 0 :(得分:1)
当您使用带有更新程序功能的setState()
时,该函数需要返回一个表示要合并的数据的对象。您没有返回任何内容,因此您的更新程序功能实际返回undefined
。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Returning_object_literals
另一个问题是你应该在你的状态下复制数组,将新数据推入其中,然后使用它来更新。永远不要改变你所在国家的情况。
onClickGroupToUpdate = (cell, row, rowIndex) => {
let toAdd = { "id": row.id, "name": row.name }
this.setState((prevState, props) => {
// Copy the array that you have in state
let datasetForStorageCopy = prevState.datasetForStorage.slice();
datasetForStorageCopy.push(toAdd)
// Return a new object describing the state change
return {datasetForStorage: datasetForStorageCopy}
})
console.log("updated the database")
console.log(this.state.datasetForStorage)
// this.forceUpdate()
}
答案 1 :(得分:1)
您没有正确使用setState,而且您正在改变它which you shouldn't。
而不是:
this.setState((prevState, props) => {
datasetForStorage: prevState.datasetForStorage.push(toAdd)
})
你可以传递一个普通的对象:
this.setState({
datasetForStorage: [...this.state.datasetForStorage,toAdd]
})
或像你一样传递函数,但注意对象周围的()
,所以我们实际返回一个对象:
this.setState((prevState, props) => ({
datasetForStorage: [...prevState.datasetForStorage,toAdd]
}))
箭头函数隐式返回,但如果使用大括号
则不会返回() => {}
所以你必须用括号包装它们
() => ({})
我使用了spread syntax来帮助我们轻松创建新数组。