微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

咖喱一个 React 钩子来跟随 DRY 是一种好习惯吗?

如何解决咖喱一个 React 钩子来跟随 DRY 是一种好习惯吗?

需要在 React 组件或自定义 React 钩子内调用 React 钩子。它不能在循环内使用。考虑到这一点,请考虑以下情况:

const useListenToStateChange = (state,onEvent,key) => {
    const value = state[key];
    useEffect(() => {
        if (value === null) {
            onEvent(null);
        } else {
            onEvent(key,value);
        }
    },[value]);
};

const ExampleComponent = (props) => {
    const { context,onError } = props;
    const { state } = useContext(context);
    
    useListenToStateChange(state,onError,KEY_ARRAY[0]);
    useListenToStateChange(state,KEY_ARRAY[1]);
    useListenToStateChange(state,KEY_ARRAY[2]);
    useListenToStateChange(state,KEY_ARRAY[3]);
    useListenToStateChange(state,KEY_ARRAY[4]);
    useListenToStateChange(state,KEY_ARRAY[5]);
    useListenToStateChange(state,KEY_ARRAY[6]);
    useListenToStateChange(state,KEY_ARRAY[7]);
    useListenToStateChange(state,KEY_ARRAY[8]);
    useListenToStateChange(state,KEY_ARRAY[9]);
    
    return <Text>{getTitle(state)}</Text>;
};

ExampleComponent 的返回值并不是真正的重点,所以可以忽略它。我担心的是 useListenToStateChange 被复制粘贴了十次,显然违反了 DRY 原则。

假设我们需要以这种方式调用 useListenToStateChange——我们需要一个监听 state 返回的 useContext 对象的值,它在执行一个带有副作用的函数时发生更改(即,无法在更新 state 的减速器内调用回调;我们需要调用 useEffect)。

这是柯里化派上用场的地方(注意:我使用 curry 中的 maplodash/fp):

const useListenToStateChange = _.curry((state,[value]);
});

const ExampleComponent = (props) => {
    const { context,onError } = props;
    const { state } = useContext(context);
    
    const listenToState = useListenToStateChange(state,onError);
    _.map(listenToState,KEY_ARRAY);
    
    return <Text>{getTitle(state)}</Text>;
};

以上代码在 React Native 中是有效的,并且运行时不会抛出错误

我喜欢它的读取方式,我喜欢这种方法使我们能够避免复制粘贴所有键。想象一下,如果您需要根据 KEY_ARRAY 数组设置多个侦听器。那将是一场噩梦。乍一看,我们也以这种方式遵循钩子规则:useListenToStateChange一个返回 JavaScript 函数的钩子,我们在 React 组件中调用该钩子。

但我正在思考的“问题”是,当你对一个函数进行柯里化时,显然它还没有执行。您必须提供最后一个参数才能运行它。这意味着 listenToState 在技术上是一个 React 钩子:当你调用它时,它会在 useEffect 内执行 useListenToStateChange 钩子。

然而,它不像钩子那样命名,因此绕过了 React 中说你必须在顶层调用它的检查。这意味着您可以映射 KEY_ARRAY,并且由于它是一个预定义的非动态数组,因此保证在每次渲染时以相同的顺序调用钩子。因此,它避免了 React docs 中概述的问题。

所以我的问题是:这种对 React 钩子进行柯里化的使用是否违反了钩子规则?换句话说,这种模式是好的做法吗?

解决方法

这种对 React 钩子进行柯里化的使用是否违反了钩子规则?

没有。用柯里化没问题。

这种模式是好的做法吗?

我觉得没问题。

但是,我不建议从外部使用状态。您可以在该函数内使用状态:

const useListenToStateChange = (onEvent,key) => {
  const { state } = useContext(YourContext);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。