可以通过挂钩来记住数量不详的组件吗?

时间:2019-07-16 22:18:35

标签: reactjs react-hooks react-dates

我正试图避免重新渲染太多子组件,但不知道如何优化以下代码:

我有一个日历形状类似的对象:

{
    2019:{
        7:{
            1:{
                avaliable: false
              },
            2:{
                avaliable: true
              }
          }
    }

}

Day组件(为简洁起见,省略了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>是重新呈现-所需的行为。

在现实生活中,创建变量并手动记录每个组件是不可能的,因为在屏幕上渲染的天数未知。

最理想的方法是什么?

1 个答案:

答案 0 :(得分:2)

React.memo类似于PureComponent的功能组件:

export default React.memo(function Day({...}) { ... })

useMemo的目的是缓存大量计算,然后阻止重新渲染。