Javascript setState()不会停止渲染
我想通过调用通过数组(从数据库调用)映射的函数来更新Javascript setState()不会停止渲染,javascript,arrays,reactjs,use-effect,use-state,Javascript,Arrays,Reactjs,Use Effect,Use State,我想通过调用通过数组(从数据库调用)映射的函数来更新useState数组值,并且useState数组将针对(数据库数组)中的每个项目进行更新,因此我尝试了以下方法: const [snapshots, setSnapshots] = useState(); const [items, setItems] = useState([]); // *** get from the database ***** // useEffect(()=> { db.collection(&q
useState
数组值,并且useState
数组将针对(数据库数组)中的每个项目进行更新,因此我尝试了以下方法:
const [snapshots, setSnapshots] = useState();
const [items, setItems] = useState([]);
// *** get from the database ***** //
useEffect(()=> {
db.collection("users").doc("4sfrRMB5ROMxXDvmVdwL").collection("basket")
.get()
.then((snapshot) => {
setSnapshots(snapshot.docs)
}
) ;
}, []);
// *** get from the database ***** //
// *** update items value ***** //
return <div className="cart__items__item">
{snapshots && snapshots.map((doc)=>(
setItems([...items, doc.data().id]),
console.log(items)
))
}
</div>
// *** update items value ***** //
我曾尝试
控制台。记录结果以查看检查问题和项数组是否连续记录在控制台中。我曾尝试将代码包含在useffect
中,但效果不佳。切勿在组件函数的顶层调用状态设置程序。对于函数组件,需要记住的一点是,当您更改状态时,您的函数将再次被调用,并具有更新的状态。如果您的代码在函数的顶层发生状态更改(正如您在问题中所做的),则每次函数运行时,您都会更改状态,导致函数运行,导致另一个状态更改,依此类推。在代码中:
const initialArray = []; // *** 1
const [Items, setItems] = useState(initialArray) // *** 2
initialArray.push("pushed item")
setItems(initialArray) // *** 3
每次创建一个新数组
创建组件时,仅使用第一个选项设置项的初始值
将新数组设置为状态,导致再次调用该函数
相反,您应该仅在响应某些更改或事件时设置状态,例如单击处理程序或其他状态更改等
还请注意,您不能直接修改处于状态的对象(包括数组)。从技术上讲,您的代码并没有做到这一点(因为每次都有一个新的initialArray
),但它看起来就像您想要做的那样。要添加到状态为的数组中,请复制该数组并在末尾添加新条目
上述情况的一个例子:
function Example() {
const [items, setItems] = useState([]);
const clickHandler = e => {
setItems([...items, e.currentTarget.value]);
};
return <div>
<div>
{items.map(item => <div key={item}>{item}</div>)}
</div>
<input type="button" value="A" onClick={clickHandler} />
<input type="button" value="B" onClick={clickHandler} />
<input type="button" value="C" onClick={clickHandler} />
</div>;
}
请注意,该代码假定doc.data().id
是一个同步操作。切勿在组件函数的顶层调用状态设置程序。对于函数组件,需要记住的一点是,当您更改状态时,您的函数将再次被调用,并具有更新的状态。如果您的代码在函数的顶层发生状态更改(正如您在问题中所做的),则每次函数运行时,您都会更改状态,导致函数运行,导致另一个状态更改,依此类推。在代码中:
const initialArray = []; // *** 1
const [Items, setItems] = useState(initialArray) // *** 2
initialArray.push("pushed item")
setItems(initialArray) // *** 3
每次创建一个新数组
创建组件时,仅使用第一个选项设置项的初始值
将新数组设置为状态,导致再次调用该函数
相反,您应该仅在响应某些更改或事件时设置状态,例如单击处理程序或其他状态更改等
还请注意,您不能直接修改处于状态的对象(包括数组)。从技术上讲,您的代码并没有做到这一点(因为每次都有一个新的initialArray
),但它看起来就像您想要做的那样。要添加到状态为的数组中,请复制该数组并在末尾添加新条目
上述情况的一个例子:
function Example() {
const [items, setItems] = useState([]);
const clickHandler = e => {
setItems([...items, e.currentTarget.value]);
};
return <div>
<div>
{items.map(item => <div key={item}>{item}</div>)}
</div>
<input type="button" value="A" onClick={clickHandler} />
<input type="button" value="B" onClick={clickHandler} />
<input type="button" value="C" onClick={clickHandler} />
</div>;
}
请注意,该代码假定doc.data().id
是一个同步操作。您在这里看到的是标准的react生命周期行为。您的组件将被装载,然后呈现(运行组件内部的所有代码)。第一次渲染后,它“侦听”组件中处理的值的更改,如果检测到任何更改,则重新渲染
你的情况:
const initialArray = [];
const [Items, setItems] = useState(initialArray)
initialArray.push("pushed item")
setItems(initialArray)
我在这里看到了两件坏事:
修改用作状态初始值的数组,并继续使用该数组更新状态
调用setItems(initialArray)
让我们把注意力集中在第二个问题上,因为这是引起你问题的原因。如果要避免无休止的渲染周期,则应将setItems()
调用移动到不在每个渲染上运行的方法。在功能组件之前,这将在componentDidMount()
函数中完成。在功能组件中,这是使用useEffect挂钩完成的:
useEffect(() => {
// Your code here
}, [])
请注意提供给useffect的空数组。此数组列出了应导致此useEffect运行的依赖项。如果将其保留为空,它将只运行一次,并与旧的componentDidMount()函数类似
因此,要解决无休止的渲染问题,需要将setItems()
移动到useffect挂钩中。这里看到的是标准的react生命周期行为。您的组件将被装载,然后呈现(运行组件内部的所有代码)。第一次渲染后,它“侦听”组件中处理的值的更改,如果检测到任何更改,则重新渲染
你的情况:
const initialArray = [];
const [Items, setItems] = useState(initialArray)
initialArray.push("pushed item")
setItems(initialArray)
我在这里看到了两件坏事:
修改用作状态初始值的数组,并继续使用该数组更新状态
调用setItems(initialArray)
让我们把注意力集中在第二个问题上,因为这是引起你问题的原因。如果要避免无休止的渲染周期,则应将setItems()
调用移动到不在每个渲染上运行的方法。在功能组件之前,这将在componentDidMount()
函数中完成。在功能组件中,这是使用useEffect挂钩完成的:
useEffect(() => {
// Your code here
}, [])
请注意提供给useffect的空数组。此数组列出了应导致此useEffect运行的依赖项。如果将其保留为空,它将只运行一次,并与旧的componentDidMount()函数类似
因此,为了解决无休止的渲染问题,您需要将setItems()
移动到useffect挂钩中。useffect(()=>{setItems(“updated value”)},[])这可能会起作用。传递空的依赖项数组,使其仅在装载后运行(运行一次),而不会在渲染函数内改变状态。通常你会称之为