0

我在道具中传递了 renderProps 函数。我想用 useCallback 包装它,所以优化的子组件不会在函数创建时重新渲染。

使用 useCallback 包装函数时,出现此错误:

无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能由于以下原因之一而发生:

  1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 你可能在同一个应用程序中拥有多个 React 副本

以上均不适用于我的情况。

renderCell = React.useCallback((
    {
      events,
      popperPlacement,
      popperStyle,
      time
    }
  ) => {
    const { localeToggle } = this.state;
    const { weekStarter, isTimeShown } = this.props;
    const eventsListPopperStyle = utils.isWeekFirst(time, weekStarter) ||
      utils.isWeekSecond(time, weekStarter) ? { left: '-17% !important' } : { left: '17% !important' };
    return (
      <MonthlyCell
        events={events}
        isTimeShown={isTimeShown}
        popperPlacement={popperPlacement}
        popperStyle={popperStyle}
        time={time}
        eventsListPopperStyle={eventsListPopperStyle}
      />
    )
  }, [])
4

1 回答 1

0

因为钩子在类组件中不起作用,所以抛出了错误。通过为 React.memo 提供第二个参数,我设法找到了解决方法。在我提供的函数中,我比较了 prevProps 和 nextProps,当 prop 是函数时,我忽略它并返回 true。它可能不适用于每个人,因为有时功能确实会发生变化,但对于没有变化的情况,没关系。

const equalizers = {
  object: (prevProp, nextProp) => JSON.stringify(prevProp) === JSON.stringify(nextProp),


  function: () => true, // disregarding function type props


  string: (prevProp, nextProp) => prevProp === nextProp,
  boolean: (prevProp, nextProp) => prevProp === nextProp,
  number: (prevProp, nextProp) => prevProp === nextProp,
}

export const areEqualProps = (prevProps, nextProps) => {
  for (const prop in prevProps) {
    const prevValue = prevProps[prop];
    const nextValue = nextProps[prop];
    if (!equalizers[typeof prevValue](prevValue, nextValue)) { return false; }
  }
  return true
}

export default React.memo(MyComponent, areEqualProps)
于 2020-08-25T13:55:48.667 回答