对于一个输出大约300个单元格的表,我有一个耗时的循环,每个单元格都有一些自定义计算,加载需要4-5秒,这是有意义的。我想在加载时显示一个加载模式。然而,模态只显示后昂贵的循环完成?
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
if(loading){
console.log(loading, "Loading has started")
}
}, [loading])
return(
<>
<Modal show={loading}>Loading....</Modal>
<a onClick={() => setLoading(true)}>Load more</a>
// Expensive loop
array.map(() => {
// HMTL
<div>
----
</div>
})
</>
)
我可以从控制台日志中看到"正在加载"的状态。已经更新,但模式尚未显示,所以我假设它等待循环完成(我不想要)。有没有办法让它输出html的模态第一还是我错过了一个基本的反应?
如果这是一个缓慢的计算,你可能不希望在每次渲染中都这样做,因为组件可以渲染很多次。理想情况下,您只希望在输入数据发生变化时进行那些昂贵的计算,这可以通过将处理和呈现分开来实现。
我不确定我完全理解这个加载部分是如何工作的,但是像这个例子应该有所帮助:
const [loading, setLoading] = useState<boolean>(false);
const [computedArray, setComputedArray] = useState([]);
useEffect(() => {
setComputedArray(array.map(//expensive loop here))
setLoading(false)
}, [array])
useEffect(() => {
if(loading){
console.log(loading, "Loading has started")
}
}, [loading])
return(
<>
<Modal show={loading}>Loading....</Modal>
<a onClick={() => setLoading(true)}>Load more</a>
// Cheap loop, turn data into markup
computedArray.map(() => {
// HTML
<div>
----
</div>
})
</>
)
我不知道Modal
是什么,所以从一般的角度回答:
个人而言,我会保持数组的状态,并在一个单独的函数中更新它,并使用&&
符号来显示Loading元素。通过这种方式,你可以将所有与昂贵的计算和加载/卸载相关的逻辑保存在一个地方。
export default function App() {
const [loading, setLoading] = useState(false);
const [array, setArray] = useState([]);
const getExpensiveCalculation = async () => {
setLoading(true);
const resultOfExpensiveCalculation = await ... // something here
// assuming result is a spreadable array too
setArray([...array, ...resultOfExpensiveCalculation]);
setLoading(false);
};
return (
<>
{loading && <Modal>Loading....</Modal>}
<a onClick={getExpensiveCalculation}>Load more</a>
{array.map(element => (
<div>
---
</div>
))}
</>
);
}