【发布时间】:2021-02-08 18:39:50
【问题描述】:
我的印象是useState 和useReducer 的工作方式相似,除了当状态是复杂/嵌套对象时我们应该使用 useReducer。
但是今天我发现了一个奇怪的行为,我正在循环一个数组并将值设置为一个状态对象。我使用useState 和useReducer 做了同样的例子。
使用useState:它只将数组中的最后一个值推送到状态对象,因为useState本质上是异步的,所以当我们在循环中设置状态时,它可能无法根据之前的状态正确更新。所以你只得到状态中的最后一个对象。
使用useReducer:我期待useReducer 具有相同的行为,但是使用useReducer,当我们从循环内部dispatch 操作时,它似乎正确设置了状态。所以在这里你可以得到状态中的所有对象。
使用状态
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
const [students, setStudents] = React.useState({});
const createStudents = () => {
const ids = [1,2,3];
const names = ['john', 'michael', 'greg']
for(let i = 0; i < 3; i++){
const student = {[ids[i]]: names[i]};
setStudents({...students, ...student})
}
}
return (
<div className="App">
<button onClick={createStudents}>Create Students</button>
<br />
{JSON.stringify(students)}
</div>
);
}
使用Reducer
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
const studentReducer = (state, action) => {
switch (action.type) {
case 'ADD':
return {...state, students: {...state.students, ...action.payload}};
default:
throw new Error();
}
}
const [students, dispatch] = React.useReducer(studentReducer, {students: {}});
const createStudents = () => {
const ids = [1,2,3];
const names = ['john', 'michael', 'greg']
for(let i = 0; i < 3; i++){
const student = {[ids[i]]: names[i]};
dispatch({type: 'ADD', payload: student})
}
}
return (
<div className="App">
<button onClick={createStudents}>Create Students</button>
<br />
{JSON.stringify(students)}
</div>
);
}
【问题讨论】:
标签: javascript reactjs react-hooks use-reducer