提问人:fadedbee 提问时间:10/8/2014 最后编辑:Or Assayagfadedbee 更新时间:2/16/2023 访问量:908137
在 React.js 中正确修改状态数组
Correct modification of state arrays in React.js
问:
我想在数组的末尾添加一个元素,这是正确的方法吗?state
this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });
我担心就地修改数组可能会导致麻烦 - 安全吗?push
制作数组副本的替代方案,这似乎是浪费。setState
答:
React 文档说:
将 this.state 视为不可变的。
您将直接更改状态,这可能会导致容易出错的代码,即使您之后再次“重置”状态。例如,这可能会导致某些生命周期方法(如不会触发)。push
componentDidUpdate
在更高版本的 React 中,推荐的方法是在修改状态时使用 updater 函数来防止争用条件:
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]
})
评论
push
setState
setState
let list = Array.from(this.state.list); list.push('woo'); this.setState({list});
正如评论中提到的@nilgun,您可以使用 react 不可变性帮助程序。我发现这非常有用。
从文档中:
简单推送
var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
initialArray 仍为 [1, 2, 3]。
评论
immutability-helper
最简单,如果您使用 .ES6
initialArray = [1, 2, 3];
newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]
新阵列将是[1,2,3,4]
在 React 中更新你的状态
this.setState({
arrayvar:[...this.state.arrayvar, newelement]
});
评论
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)。
buggy onClick 只会添加“Third”,但固定的 Bug 会按预期添加 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])
这将改变以前的状态对象。
最简单的方法:ES6
this.setState(prevState => ({
array: [...prevState.array, newElement]
}))
评论
tableData = [['test','test']]
tableData = [['test','test'],['new','new']]
[['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]);
这段代码对我有用:
fetch('http://localhost:8080')
.then(response => response.json())
.then(json => {
this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})
评论
.push
返回一个数字,而不是一个数组。
我正在尝试在数组状态中推送值并像这样设置值,并通过映射函数定义状态数组和推送值。
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})
})
对于将新元素添加到数组中,应该是答案。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);
评论
如果您使用的是功能组件,请按如下方式使用。
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
评论
//------------------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;
}));
这对我在数组中添加数组有用
this.setState(prevState => ({
component: prevState.component.concat(new Array(['new', 'new']))
}));
这是一个 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(', '))
}
}
评论
当我想修改数组状态时,我遇到了类似的问题 同时保留元素在数组中的位置
这是一个在喜欢和不喜欢之间切换的功能:
const liker = (index) =>
setData((prevState) => {
prevState[index].like = !prevState[index].like;
return [...prevState];
});
正如我们所说,该函数在数组状态中获取元素的索引,然后我们继续修改旧状态并重建状态树
评论
如果你在 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);
目前很多人都面临着更新useState钩子状态的问题。我使用这种方法来安全地更新它,并想在这里分享它。
这是我的状态
const [state, setState] = useState([])
假设我有一个对象名称,我希望它附加到我的状态中。我会建议这样做obj1
setState(prevState => [...prevState, obj1])
这将安全地在末尾插入对象,并保持状态一致性
评论
setState((state) => ...
this.setState(preState=>({arrayvar:[...prevState.arrayvar,newelement]}))
这将解决这个问题。
评论
//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) })
我所做的是更新状态之外的值并执行 forceupdate(),react 管理的东西越少越好,因为您可以更好地控制更新的内容。 此外,如果更新速度很快,则为每次更新创建新阵列可能成本太高
评论