0

我有一个表格,里面有会议预订。其中一部分是日历组件,它具有相当复杂的 UI。

<Calendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />

这工作正常。

正如 React 用户所知道的,当任何输入发生变化时,react 会重新渲染表单。由于日历仅依赖于某些输入(和),而不依赖于其他输入fullName,并且绘制速度很慢,我想用它来停止日历重新渲染:emailonEventScheduleduseMemo()

(根据@dmitryguzeev 评论更新为使用 JSX)

  const MemoizedCalendar = useMemo(() => {
    return <Calendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />;
  }, [email, fullName, onEventScheduled]);

然后后来

<MemoizedCalendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />

但是切换到 MemoizedCalendar 会出现以下错误:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `Formik`.

(我碰巧在使用 Formik,但是该组件可以正常工作Calendar,只是MemoizedCalendar失败了)

编辑:阅读这篇关于 UseMemo() 的文章useCallback()后,我也尝试过

值得一提的是,如果组件接收到一个函数作为 props,则需要使用 useCallback 钩子,以便它只在必要时再次声明该函数。否则每次渲染时 props 都会不同,因为函数 prop 总是有一个新的引用。

const MemoizedCalendar = useCallback(() => {
    return Calendar(email, fullName, onEventScheduled);
  }, [email, fullName, onEventScheduled]);

email这修复了错误,但在,fullName和之外的项目onEventScheduled被修改时仍会不必要地重新渲染。

我怎样才能记住这个钩子组件?

4

1 回答 1

1

要使用 来记忆您的组件 JSX 树部分useMemo,您需要首先在以下内容中单独渲染它useMemo

// I usually prefix the name of this variable with rendered* so
// that the user below knows how to use it properly
const renderedCalendar = useMemo(() => {
  // This code below tells react to render Calendar with given props.
  // This JSX will be transformed into a function call and it will
  // happen only after the dependency array given to useMemo changes.
  return <Calendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />
}, [fullName, email, onEventScheduled]);

然后将其用作值而不是 JSX 树中的组件:

return (
  <div>
    ...
    {renderedCalendar}
  </div>
);
于 2021-04-16T12:41:33.573 回答