首页 > 解决方案 > 在 React 中有条件地执行 useContext

问题描述

我希望有条件地调用 useContext。这是我的原始代码,它运行正确,但 tslint 失败。

调用useResourceScope的组件- 比如说Component1

import { useEffect } from 'react';

export function useSubscribeListItemStore(
  inputResources?: ResourceScope
) {
  const resources = inputResources || useResourceScope();
  const listItemStore = resources.consume(listItemStoreKey);
  
  useEffect(function subscribeListItemStore() {
    // do some logic
  }, []);
}

定义useResourceScope的组件- 比如说Component2

import { createContext } from 'preact';
import { useContext } from 'preact/hooks';

export const ResourceScopeContext = createContext<ResourceScope | undefined>(undefined);

export function useResourceScope(): ResourceScope {
  const resources = useContext(ResourceScopeContext);
  if (!resources) {
    throw new Error(
      'error message'
    );
  }
  return resources;
}

这给了我一个 tslint 错误:(react-hooks-nesting)钩子不能用于条件表达式

这是我解决这个问题的尝试,但不起作用。它无法正确运行,并且在Component2中的useContext行失败我的想法是,由于必须调用useContext来修复 tslint 错误,所以我决定有条件地使用不同创建的上下文调用 useContext。如果变量被传入,它会调用一个名为 的占位符上下文,它会忽略并返回。如果不是,它会使用预期值。 inputResourcesuseContextPlaceHolderContextinputResourcesuseContextResourceScopeContext

调用useResourceScope的组件- 比如说Component1

import { useEffect } from 'react';

export function useSubscribeListItemStore(
  inputResources?: ResourceScope
) {
  const resources = useResourceScope(inputResources);
  const listItemStore = resources.consume(listItemStoreKey);
  
  useEffect(function subscribeListItemStore() {
    // do some logic
  }, []);
}

定义useResourceScope的组件- 比如说Component2

import { createContext } from 'preact';
import { useContext } from 'preact/hooks';

export const ResourceScopeContext = createContext<ResourceScope | undefined>(undefined);

export function useResourceScope(inputResources?: ResourceScope): ResourceScope {
  const PlaceHolderContext = createContext({ foo: 'bar' });
  const createdContext = inputResources ? PlaceHolderContext : ResourceScopeContext;

  const resources = useContext(createdContext as any);

  if (inputResources) {
    return inputResources;
  }

  if (!resources) {
    throw new Error(
      'error message'
    );
  }
  return resources as any;
}

你能建议我如何在这里解决 tslint 错误而不破坏它吗?

标签: reactjsreact-hookspreactuse-contextcreatecontext

解决方案


与其有条件地调用钩子,不如有条件地使用它的返回值?

import { useEffect } from 'react';

export function useSubscribeListItemStore(
  inputResources?: ResourceScope
) {
  const contextResources = useResourceScope();
  const resources = inputResources || contextResources;

  const listItemStore = resources.consume(listItemStoreKey);
  
  useEffect(function subscribeListItemStore() {
    // do some logic
  }, []);
}

推荐阅读