我不清楚它是什么,但是在尝试使用钩子对数组进行最简单的状态更新时遇到了无数问题。
我发现唯一起作用的方法是使用useReducer通过在onClick处理程序上进行分派对数组执行单个更新。在我当前的项目中,我试图在嵌套在表单提交中运行的函数中的for循环中更新数组状态。我尝试了许多不同的解决方案,但这只是我的尝试之一。
function sessionToState(session) {
let formattedArray = []
for (let i = 0; i < session.length; i++) {
formattedArray.push({ url: session[i] })
setLinksArray([...linksArray, formattedArray[i]])
}
}
// --------------------------------------------------------
return (
<div>
<form
method="post"
onSubmit={async e => {
e.preventDefault()
const session = await getURLs({ populate: true })
sessionToState(session)
await createGroup()
我想知道我是否缺少任何重要的东西,或者关于如何使用钩子处理数组的一些技巧和窍门。如果需要更多信息,请随时询问。谢谢。
答案 0 :(得分:2)
从嵌套函数调用中调用状态设置器时,应使用functional update form of setState
。在您的情况下,将是:
setLinksArray(linksArray => [...linksArray, formattedArray[i]])
目前还不清楚您遇到什么样的问题,但是上述修复程序将使您从linksArray
的意外状态中解放出来。
这也适用于任何状态,不仅适用于数组。
答案 1 :(得分:2)
明智地,您不应该每次迭代都调用const object1 = { foo: 'bar', baz: 42 };
console.log(Object.entries(object1)[1]);
// expected output: Array ["baz", 42]
const object2 = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(object2)[2]);
// expected output: Array ["2", "c"]
const result = Object.entries(object2).sort((a, b) => a - b);
console.log(Object.entries(result)[1]);
。您应该使用最终数组设置状态。
setState
...或者如果您也想保留旧项目,则应使用setState中的函数进行操作...
const sessionToState = (session) => {
setLinksArray(
session.map(sessionItem => ({url: sessionItem}))
);
}
答案 2 :(得分:1)
我想知道我是否还有大事想念
TLDR:setLinksArray
不会在当前渲染器中更新linksArray
,但会在下一个渲染器中更新。
假设变量的初始化如下:
const [linksArray, setLinksArray] = useState([])
const
关键字中有一个提示,linksArray
是1个渲染中的常数(并且这个事实在let
中不会改变,因为它是useState
的工作原理)。
setLinksArray()
的想法是在下一个渲染中使强度值不同。
所以for
循环类似于:
setLinksArray([...[], session0])
setLinksArray([...[], session1])
setLinksArray([...[], session2])
,您将在下一个渲染中得到linksArray = [session2]
。
保持理智的最佳方法是每个渲染的每个状态仅一次调用任何setState
函数(尽管可以有多个状态),对代码的更改最小:
function sessionToState(session) {
let formattedArray = []
for (let i = 0; i < session.length; i++) {
formattedArray.push({ url: session[i] })
}
setLinksArray(formattedArray)
}
此外,如果您需要在所有setState
函数完成其工作后(即NEXT渲染之后)执行副作用(例如API调用),则需要useEffect
:
useEffect(() => {
...do something with updated linksArray...
}, [linksArray])