我想在 state
数组的末尾添加一个元素,这是正确的方法吗?
this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });
我担心使用 push
就地修改数组可能会导致麻烦 - 它安全吗?
制作数组副本的替代方法,setState
这似乎很浪费。
React docs 说:
将 this.state 视为不可变的。
您的 push
将直接改变状态,这可能会导致容易出错的代码,即使您之后再次“重置”状态也是如此。例如,它可能导致某些生命周期方法(如 componentDidUpdate
)不会触发。
在更高版本的 React 版本中推荐的方法是在修改状态时使用更新函数来防止竞争条件:
this.setState(prevState => ({
arrayvar: [...prevState.arrayvar, newelement]
}))
与使用非标准状态修改可能面临的错误相比,内存“浪费”不是问题。
早期 React 版本的替代语法
您可以使用 concat
获得干净的语法,因为它返回一个新数组:
this.setState({
arrayvar: this.state.arrayvar.concat([newelement])
})
在 ES6 中,您可以使用 Spread Operator:
this.setState({
arrayvar: [...this.state.arrayvar, newelement]
})
最简单,如果您使用 ES6
。
initialArray = [1, 2, 3];
newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]
新数组将为 [1,2,3,4]
在 React 中更新你的状态
this.setState({
arrayvar:[...this.state.arrayvar, newelement]
});
Learn more about array destructuring
ES6
最简单的方法:
this.setState(prevState => ({
array: [...prevState.array, newElement]
}))
tableData = [['test','test']]
推送我的新数组 tableData = [['test','test'],['new','new']]
后。如何推动这个@David 和@Ridd
[['test','test'],['new','new']]
,请尝试:this.setState({ tableData: [...this.state.tableData, ['new', 'new']]
this.setState({ tableData: [...this.state.tableData ,[item.student_name,item.homework_status_name,item.comments===null?'-':item.comments] ] });
它两次插入新数组 this.state.tableData.push([item.student_name,item.homework_status_name,item.comments===null?'-':item.comments]);
它实现了我想要的东西。但它不是我认为的正确方式。
React 可能会批量更新,因此正确的方法是为 setState 提供一个执行更新的函数。
对于 React 更新插件,以下内容将可靠地工作:
this.setState( state => update(state, {array: {$push: [4]}}) );
或者对于 concat():
this.setState( state => ({
array: state.array.concat([4])
}));
下面以 https://jsbin.com/mofekakuqi/7/edit?js,output 为例说明如果你弄错了会发生什么。
setTimeout() 调用正确地添加了三个项目,因为 React 不会在 setTimeout 回调中批量更新(请参阅 https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ)。
有问题的 onClick 只会添加“第三”,但固定的会按预期添加 F、S 和 T。
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
array: []
}
setTimeout(this.addSome, 500);
}
addSome = () => {
this.setState(
update(this.state, {array: {$push: ["First"]}}));
this.setState(
update(this.state, {array: {$push: ["Second"]}}));
this.setState(
update(this.state, {array: {$push: ["Third"]}}));
};
addSomeFixed = () => {
this.setState( state =>
update(state, {array: {$push: ["F"]}}));
this.setState( state =>
update(state, {array: {$push: ["S"]}}));
this.setState( state =>
update(state, {array: {$push: ["T"]}}));
};
render() {
const list = this.state.array.map((item, i) => {
return <li key={i}>{item}</li>
});
console.log(this.state);
return (
<div className='list'>
<button onClick={this.addSome}>add three</button>
<button onClick={this.addSomeFixed}>add three (fixed)</button>
<ul>
{list}
</ul>
</div>
);
}
};
ReactDOM.render(<List />, document.getElementById('app'));
this.setState( update(this.state, {array: {$push: ["First", "Second", "Third"]}}) )
state.array = state.array.concat([4])
这会改变先前的状态对象。
如果你在 React 中使用函数式组件
const [cars, setCars] = useState([{
name: 'Audi',
type: 'sedan'
}, {
name: 'BMW',
type: 'sedan'
}])
...
const newCar = {
name: 'Benz',
type: 'sedan'
}
const updatedCarsArray = [...cars, newCar];
setCars(updatedCarsArray);
正如评论中提到的@nilgun,您可以使用react immutability helpers。我发现这非常有用。
从文档:
简单推送
var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
initialArray 仍然是 [1, 2, 3]。
immutability-helper
表达了这种担忧,并且在这个方向上有很多想法和代码。
目前有很多人面临更新 useState 挂钩状态的问题。我使用这种方法安全地更新它并想在这里分享它。
这是我的状态
const [state, setState] = useState([])
假设我有一个对象名称 obj1
,并且我希望它附加到我的状态中。我会建议这样做
setState(prevState => [...prevState, obj1])
这将在最后安全地插入对象并保持状态一致性
setState((state) => ...
,参见en.reactjs.org/docs/react-component.html#setstate -- 状态更新不会立即发生,所以在使用原始状态时变量,某些更新可能会被新的更新覆盖。
如果您正在使用功能组件,请按如下方式使用。
const [chatHistory, setChatHistory] = useState([]); // define the state
const chatHistoryList = [...chatHistory, {'from':'me', 'message':e.target.value}]; // new array need to update
setChatHistory(chatHistoryList); // update the state
对于向数组中添加新元素,push()
应该是答案。
对于数组的删除元素和更新状态,下面的代码适用于我。 splice(index, 1)
无法工作。
const [arrayState, setArrayState] = React.useState<any[]>([]);
...
// index is the index for the element you want to remove
const newArrayState = arrayState.filter((value, theIndex) => {return index !== theIndex});
setArrayState(newArrayState);
push
改变数组,which is an anti-pattern in React.
这是一个 2020 年的 Reactjs Hook 示例,我认为它可以帮助其他人。我正在使用它向 Reactjs 表添加新行。让我知道我是否可以改进一些东西。
向功能状态组件添加新元素:
定义状态数据:
const [data, setData] = useState([
{ id: 1, name: 'John', age: 16 },
{ id: 2, name: 'Jane', age: 22 },
{ id: 3, name: 'Josh', age: 21 }
]);
有一个按钮触发一个添加新元素的功能
<Button
// pass the current state data to the handleAdd function so we can append to it.
onClick={() => handleAdd(data)}>
Add a row
</Button>
function handleAdd(currentData) {
// return last data array element
let lastDataObject = currentTableData[currentTableData.length - 1]
// assign last elements ID to a variable.
let lastID = Object.values(lastDataObject)[0]
// build a new element with a new ID based off the last element in the array
let newDataElement = {
id: lastID + 1,
name: 'Jill',
age: 55,
}
// build a new state object
const newStateData = [...currentData, newDataElement ]
// update the state
setData(newStateData);
// print newly updated state
for (const element of newStateData) {
console.log('New Data: ' + Object.values(element).join(', '))
}
}
由于不允许直接改变状态,因此不能简单地将项目推送到数组。
state = {
value: '',
list: ['a', 'b', 'c'],
};
this.setState({
list: [...this.state.list, newelement]
})
//or
onAddItem = () => {
// not allowed AND not working
this.setState(state => {
const list = state.list.push(state.value);
return {
list,
value: '',
};
});
};
this.setState(preState=>({arrayvar:[...prevState.arrayvar,newelement]}))
这将解决这个问题。
我所做的是更新状态之外的值并执行 forceupdate(),反应管理的内容越少越好,因为您可以更好地控制更新的内容。如果更新速度很快,还为每次更新创建一个新数组可能会太昂贵
我正在尝试在数组状态中推送值并像这样设置值,并通过映射函数定义状态数组和推送值。
this.state = {
createJob: [],
totalAmount:Number=0
}
your_API_JSON_Array.map((_) => {
this.setState({totalAmount:this.state.totalAmount += _.your_API_JSON.price})
this.state.createJob.push({ id: _._id, price: _.your_API_JSON.price })
return this.setState({createJob: this.state.createJob})
})
当我想修改数组状态同时保留数组中元素的位置时,我遇到了类似的问题
这是一个在喜欢和不喜欢之间切换的功能:
const liker = (index) =>
setData((prevState) => {
prevState[index].like = !prevState[index].like;
return [...prevState];
});
正如我们可以说的那样,该函数获取数组状态中元素的索引,然后我们继续修改旧状态并重建状态树
//get the value you want to add
const valor1 = event.target.elements.valor1.value;
//add in object
const todo = {
valor1,
}
//now you just push the new value into the state
//prevlista is the value of the old array before updating, it takes the old array value makes a copy and adds a new value
setValor(prevLista =>{
return prevLista.concat(todo) })
这对我来说可以在数组中添加一个数组
this.setState(prevState => ({
component: prevState.component.concat(new Array(['new', 'new']))
}));
//------------------code is return in typescript
const updateMyData1 = (rowIndex:any, columnId:any, value:any) => {
setItems(old => old.map((row, index) => {
if (index === rowIndex) {
return Object.assign(Object.assign({}, old[rowIndex]), { [columnId]: value });
}
return row;
}));
这段代码对我有用:
fetch('http://localhost:8080')
.then(response => response.json())
.then(json => {
this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})
.push
returns a number 以来未能正确更新组件的状态,而不是数组。
不定期副业成功案例分享
push
返回新的数组长度,这样就行不通了。此外,setState
是异步的,React 可以将多个状态更改排队到单个渲染通道中。setState
两次,它显示了两个类似的设置状态数组而不直接改变它的例子。let list = Array.from(this.state.list); list.push('woo'); this.setState({list});
当然要根据您的样式偏好进行修改。