如何将元素推入useState数组React钩子中?这是处于响应状态的旧方法吗?还是新东西?
如何将元素推入useState数组React钩子中?这是处于响应状态的旧方法吗?还是新东西?
Answers:
使用时useState
,您可以获取状态项的更新方法:
const [theArray, setTheArray] = useState(initialArray);
然后,当您要添加新元素时,可以使用该函数并传入新数组或将创建新数组的函数。通常情况下是后者,因为状态更新是异步的,有时是分批的:
setTheArray(oldArray => [...oldArray, newElement]);
有时,如果您仅针对某些特定的用户事件click
(例如,但不喜欢mousemove
)更新处理程序中的数组,则无需使用回调形式就可以摆脱困境:
setTheArray([...theArray, newElement]);
React保证刷新渲染的事件是此处列出的“离散事件” 。
实时示例(将回调传递给setTheArray
):
因为其中的唯一更新theArray
是click
事件中的一个(“离散”事件之一),所以我可以通过直接更新来解决addEntry
:
useEffect
示例中说的是什么...?
useEffect
依赖项列表为空[]
,则它将仅在第一个渲染期间执行。因此,theArray
内部效果的值将始终为initialArray
。在setTheArray([...initialArray, newElement])
没有意义的情况下,并且当theArray
常数始终等于时initialValue
,则需要功能更新。
setTheArray(()=>theArray.concat(newElement))
可以,但是不可以!回调的参数使所有差异。
为了进一步扩展,下面是一些常见示例。从...开始:
const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);
在数组末尾推送元素
setTheArray(prevArray => [...prevArray, newValue])
在对象末尾推送/更新元素
setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));
在对象数组末尾推送/更新元素
setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);
将元素推入数组对象的末尾
let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);
在React类组件中以“正常”状态进行操作的方式相同。
例:
function App() {
const [state, setState] = useState([]);
return (
<div>
<p>You clicked {state.join(" and ")}</p>
//destructuring
<button onClick={() => setState([...state, "again"])}>Click me</button>
//old way
<button onClick={() => setState(state.concat("again"))}>Click me</button>
</div>
);
}
// Save search term state to React Hooks with spread operator and wrapper function
// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))
// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))
// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])
// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])
https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc
setTheArray([...theArray, newElement]);
是最简单的答案,但要注意theArray中项目的突变。使用数组项目的深克隆。
推荐的方法是一起使用包装函数和散布运算符。例如,如果您初始化了这样的状态name
,
const [names, setNames] = useState([])
您可以像这样推送到该数组,
setNames(names => [...names, newName])
希望能有所帮助。
您可以在自定义状态的末尾追加数据数组:
const [vehicleData, setVehicleData] = React.useState<any[]>([]);
setVehicleData(old => [...old, ...newArrayData]);
例如,在下面,您将显示axios的示例:
useEffect(() => {
const fetchData = async () => {
const result = await axios(
{
url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
method: 'get',
}
);
setVehicleData(old => [...old, ...result.data.data]);
};
fetchData();
}, [page]);
我尝试了上述方法将对象推入useState中的对象数组,但使用TypeScript时出现以下错误:
输入'TxBacklog [] | 未定义”必须具有返回iterator.ts(2488)的“ Symbol.iterator”方法
tsconfig.json的设置显然是正确的:
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es6",
],
该解决方法解决了该问题(我的示例代码):
接口:
interface TxBacklog {
status: string,
txHash: string,
}
状态变量:
const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();
将新对象推入数组:
// Define new object to be added
const newTx = {
txHash: '0x368eb7269eb88ba86..',
status: 'pending'
};
// Push new object into array
(txBacklog)
? setTxBacklog(prevState => [ ...prevState!, newTx ])
: setTxBacklog([newTx]);
如果要推送特定索引,可以执行以下操作:
const handleAddAfterIndex = index => {
setTheArray(oldItems => {
const copyItems = [...oldItems];
const finalItems = [];
for (let i = 0; i < copyItems.length; i += 1) {
if (i === index) {
finalItems.push(copyItems[i]);
finalItems.push(newItem);
} else {
finalItems.push(copyItems[i]);
}
}
return finalItems;
});
};
setTheArray(currentArray => [...currentArray, newElement])
上述方法不起作用。最有可能的useEffect(...theArray..., [])
,它认识到这一点很重要theArray
是恒定的,所以功能的更新,需要从未来的价值渲染