是否可以使用钩子记忆未知数量的组件?
Is it possible to Memoize an unkown number of Components with hooks?
我试图避免太多的子组件重新渲染,但不知道如何优化下面的代码:
我有一个日历形状如下的对象:
{
2019:{
7:{
1:{
avaliable: false
},
2:{
avaliable: true
}
}
}
}
日期组件(为简洁起见省略了 setAgenda 逻辑):
function Day(props) {
<span style={{ color: props.avaliable ? "blue" : "red" }}>
{props.day}
</span>
}
日历组件:
function Calendar() {
const [agenda, setAgenda] = useState(initialAgenda);
renderMonth = () => {
return(
<>
<Day day={1}
avaliable={agenda["2019"]["7"]["1"].avaliable}
memoized={false}
setAgenda={setAgenda}
/>
<Day day={2}
avaliable={agenda["2019"]["7"]["2"].avaliable}
memoized={false}
setAgenda={setAgenda}
/>
</>
}
return(
<>
{renderMonth()}
</>
)
}
每次我更新一天的 avaliable
属性 时,日历中呈现的每个 <Day>
都会重新呈现。不仅如此,每当日历内部状态的任何部分更新时,<Day>
也会重新呈现。
试验 useMemo,我想到了这个:
const day1 = agenda["2019"]["7"]["1"].avaliable;
const memoDay1 = useMemo(
() => (
<Day day={1} avaliable={day1} memoized={true} setAgenda={setAgenda}/>
),
[day1]
);
因此更新后的日历组件如下所示:
function Calendar() {
const [agenda, setAgenda] = useState(initialAgenda);
const day1 = agenda["2019"]["7"]["1"].avaliable;
const memoizedDay1 = useMemo(
() => (
<Day day={1} avaliable={day1} memoized={true} setAgenda={setAgenda}/>
),
[day1]);
const day2 = agenda["2019"]["7"]["2"].avaliable;
const memoizedDay2 = useMemo(
() => (
<Day day={2} avaliable={day2} memoized={true} setAgenda={setAgenda}/>
),
[day2]);
renderMonth = () => {
return(
<>
{memoizedDay1}
{memoizedDay2}
</>
}
return(
<>
{renderMonth()}
</>
)
}
现在不需要重新渲染了,当我更新一天时,只有一个 <Day>
被重新渲染,如果我更新日历组件的内部状态,没有 <Day>
重新呈现 - 所需的行为。
在现实生活中,创建一个变量并手动记忆每个组件是不可能的,因为它在屏幕上呈现的天数是未知的。
理想的方法是什么?
将React.memo
用作功能组件的PureComponent
类比:
export default React.memo(function Day({...}) { ... })
目的 useMemo
是缓存繁重的计算然后防止 re-rendering。
我试图避免太多的子组件重新渲染,但不知道如何优化下面的代码:
我有一个日历形状如下的对象:
{
2019:{
7:{
1:{
avaliable: false
},
2:{
avaliable: true
}
}
}
}
日期组件(为简洁起见省略了 setAgenda 逻辑):
function Day(props) {
<span style={{ color: props.avaliable ? "blue" : "red" }}>
{props.day}
</span>
}
日历组件:
function Calendar() {
const [agenda, setAgenda] = useState(initialAgenda);
renderMonth = () => {
return(
<>
<Day day={1}
avaliable={agenda["2019"]["7"]["1"].avaliable}
memoized={false}
setAgenda={setAgenda}
/>
<Day day={2}
avaliable={agenda["2019"]["7"]["2"].avaliable}
memoized={false}
setAgenda={setAgenda}
/>
</>
}
return(
<>
{renderMonth()}
</>
)
}
每次我更新一天的 avaliable
属性 时,日历中呈现的每个 <Day>
都会重新呈现。不仅如此,每当日历内部状态的任何部分更新时,<Day>
也会重新呈现。
试验 useMemo,我想到了这个:
const day1 = agenda["2019"]["7"]["1"].avaliable;
const memoDay1 = useMemo(
() => (
<Day day={1} avaliable={day1} memoized={true} setAgenda={setAgenda}/>
),
[day1]
);
因此更新后的日历组件如下所示:
function Calendar() {
const [agenda, setAgenda] = useState(initialAgenda);
const day1 = agenda["2019"]["7"]["1"].avaliable;
const memoizedDay1 = useMemo(
() => (
<Day day={1} avaliable={day1} memoized={true} setAgenda={setAgenda}/>
),
[day1]);
const day2 = agenda["2019"]["7"]["2"].avaliable;
const memoizedDay2 = useMemo(
() => (
<Day day={2} avaliable={day2} memoized={true} setAgenda={setAgenda}/>
),
[day2]);
renderMonth = () => {
return(
<>
{memoizedDay1}
{memoizedDay2}
</>
}
return(
<>
{renderMonth()}
</>
)
}
现在不需要重新渲染了,当我更新一天时,只有一个 <Day>
被重新渲染,如果我更新日历组件的内部状态,没有 <Day>
重新呈现 - 所需的行为。
在现实生活中,创建一个变量并手动记忆每个组件是不可能的,因为它在屏幕上呈现的天数是未知的。
理想的方法是什么?
将React.memo
用作功能组件的PureComponent
类比:
export default React.memo(function Day({...}) { ... })
目的 useMemo
是缓存繁重的计算然后防止 re-rendering。