【发布时间】:2021-04-16 20:41:33
【问题描述】:
我有一个表格,里面有会议预订。其中一部分是日历组件,它具有相当复杂的 UI。
<Calendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />
这很好用。
正如 React 用户所知道的,当任何输入发生变化时,React 都会重新呈现表单。由于日历仅依赖于某些输入(fullName、email 和 onEventScheduled),而不依赖于其他输入,并且绘制速度很慢,我想使用 useMemo() 来停止日历重新渲染:
(根据@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 失败)
编辑:在reading this article on UseMemo()之后我也试过useCallback()
值得一提的是,如果一个组件接收到一个函数作为 props,你需要使用 useCallback 钩子,以便它只在必要时再次声明该函数。否则每次渲染时 props 都会不同,因为函数 prop 总是有一个新的引用。
const MemoizedCalendar = useCallback(() => {
return Calendar(email, fullName, onEventScheduled);
}, [email, fullName, onEventScheduled]);
这修复了错误,但在 email、fullName 和 onEventScheduled 之外的项目被修改时仍会不必要地重新渲染。
如何记忆这个钩子组件?
【问题讨论】:
-
Calendar 是一个 React 组件,而不是一个简单的类。您需要在
useMemo中使用 JSX 语法才能使其工作:return <Calendar fullName={fullName} email={email} onEventScheduled={onEventScheduled} />。 -
您还需要将 memoized 值用作已渲染的组件,而不是要渲染的组件。这样做:
const memoizedCalendar = useMemo(...)然后在你的 JSX 中{memoizedCalendar} -
在下面添加了答案
标签: javascript reactjs react-hooks react-usememo