首页 > 解决方案 > 是否可以有条件地使用 useCallback React hook,即使它违反了 hooks 的规则?

问题描述

我试图找出一种方法来通过指定特定的道具来记忆 React 组件。

例如,如果你使用React.memo- 它会根据所有 props 来记忆组件。

我想要实现的是能够将特定的道具作为依赖项传递给 util(比如,SuperMemo),并且组件将根据这些道具进行记忆。该方法与recompose非常相似——在导出之前组合组件。

这是一个示例代码

import React from "react";

const isFunction = value =>
  value &&
  (Object.prototype.toString.call(value) === "[object Function]" ||
    "function" === typeof value ||
    value instanceof Function);

export const memo = (Comp, resolver) => {
  if (isFunction(resolver)) {
    const Memoized = props => {
      const deps = resolver(props);
      if (deps && deps.length) {
        // eslint-disable-next-line react-hooks/rules-of-hooks
        return React.useCallback(React.createElement(Comp, props), deps);
      }

      return React.createElement(Comp, props);
    };

    Memoized.displayName = `memoized(${Comp.name})`;
    return Memoized;
  }

  return React.memo(Comp);
};

export default memo;

以下是如何使用它来组合组件

import Todo from "./Todo";
import memo from "../memo";

export default memo(Todo, props => [props.text]);

我在这里有一个可用的代码和框——memo -deps

这是我观察到的——</p>

这是我不确定发生了什么的地方(这些是我的问题)-</p>

我为什么要这样做的原因——</p>

我不想每次将处理程序(带有值和事件的闭包)传递给包装在React.memo. 我希望能够以声明方式为组件编写 memoize 依赖项。

标签: javascriptreactjsreact-hooks

解决方案


React.memo接受一个函数作为第二个参数来进行自定义道具比较。

默认情况下,它只会对 props 对象中的复杂对象进行浅层比较。如果要控制比较,还可以提供自定义比较函数作为第二个参数。

您可以像这样在您的 util 函数中使用它:

export const memoWithSecondParam = (Comp, deps = []) => {
  return React.memo(Comp, (prevProps, nextProps) => {
    return deps.every(d => prevProps[d] === nextProps[d])
  });
};

并这样称呼它:

export default memoWithSecondParam(Todo, ["text"]);

推荐阅读