在过去的几年里,我曾多次遇到此类问题,但只是将低效的代码保留在原地,因为找不到明确的方法来解决它。所以我最后问一下如何很好地解决它。
这是一些隔离核心问题的基本代码。我下面有一个
useState(complexDefaultComputation)
,我想知道如何在每次渲染后不计算它,这也不必求助于 useEffect
来设置初始值。
import React, { useState } from 'react';
import _ from 'lodash';
type MyRecord = {
id: string;
// 20 more props...
};
export default function MyComponent({ records }: { records: Array<MyRecord> }) {
const [lastPageLoadedIndex, setLastPageLoadedIndex] = useState(0);
const [pages, setPages] = useState(
_.chunk(records, 10).map((chunk, i) => ({
records: chunk,
loaded: i === 0,
}))
);
const handleClick = () => {
const page = pages[lastPageLoadedIndex + 1];
// async fetch pages...
// then update state
pages[lastPageLoadedIndex + 1] = { ...page, loaded: true };
setLastPageLoadedIndex((i) => i + 1);
setPages([...pages]);
};
return (
<div>
{pages
.map((page, pageIndex) =>
page.loaded
? page.records.map((record, recordIndex) => (
<div key={`record-${pageIndex}-${recordIndex}`}>
{record.id}
</div>
))
: []
)
.flat()}
<button onClick={handleClick}>Load next</button>
</div>
);
}
我怎样才能做到这一点?
我尝试过:
useEffect
设置初始值,但随后它必须至少渲染两次,并且我们没有获得SEO好处。useMemo
设置默认值,然后是带有记忆值的 useState
?这是理想的方法吗?您可以使用初始化代码将函数传递到
useState
。该函数只会在第一次渲染时被调用,它的返回值将成为初始状态。
const [pages, setPages] = useState(
() => _.chunk(records, 10).map((chunk, i) => ({
records: chunk,
loaded: i === 0,
}))
);