正确修改React.js中的状态数组

我想在state数组的末尾添加一个元素,这是正确的方法吗?

this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });

我担心用push修改数组可能会带来麻烦——它安全吗?

另一种方法是复制数组,setStateing,这看起来很浪费。

821481 次浏览

反应文档表示:

对待这个问题。状态,仿佛它是不可变的。

您的push将直接改变状态,这可能会潜在地导致容易出错的代码,即使您正在“重置”。国家再次之后。例如,它可能导致一些生命周期方法(如componentDidUpdate)无法触发。

在后续的React版本中,推荐的方法是在修改状态以防止竞争条件时使用更新器函数:

this.setState(prevState => ({
arrayvar: [...prevState.arrayvar, newelement]
}))

记忆“浪费”;与使用非标准状态修改可能面临的错误相比,这不是一个问题。

早期React版本的替代语法

你可以使用concat来获得一个干净的语法,因为它返回一个新数组:

this.setState({
arrayvar: this.state.arrayvar.concat([newelement])
})

在ES6中,你可以使用传播算子:

this.setState({
arrayvar: [...this.state.arrayvar, newelement]
})

正如@nilgun在评论中提到的,你可以使用不变性的帮手反应。我发现这非常有用。

从文档中可以看出:

简单的推

var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

initialArray仍然是[1,2,3]。

如果您使用ES6,这是最简单的方法。

initialArray = [1, 2, 3];


newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]

新数组将是[1,2,3,4]

反应中更新你的状态

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)。

错误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'));

使用ES6最简单的方法:

this.setState(prevState => ({
array: [...prevState.array, newElement]
}))

这段代码为我工作:

fetch('http://localhost:8080')
.then(response => response.json())
.then(json => {
this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})

我试图在数组状态下推值,并像这样设置值,并通过映射函数定义状态数组和推值。

 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(', '))
}


}

当我想修改数组状态时,我有类似的问题 同时保留元素在数组中的位置

这是一个在like和different之间切换的函数:

    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])

这将安全地在末尾插入对象,并保持状态一致性

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管理的东西越少越好,因为您可以更好地控制更新的内容。 此外,如果更新速度很快,为每次更新创建一个新数组可能代价太大