在 React 中有条件地执行 useContext

Lea*_*ove 6 reactjs preact react-hooks use-context createcontext

我希望有条件地调用 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
  }, []);
}
Run Code Online (Sandbox Code Playgroud)

定义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;
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个 tslint 错误:(react-hooks-nesting) A hook不能在条件表达式中使用

这是我尝试解决这个问题,但不起作用。它无法正确运行,并且在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
  }, []);
}
Run Code Online (Sandbox Code Playgroud)

定义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;
}
Run Code Online (Sandbox Code Playgroud)

您能否建议我如何解决此处的 tslint 错误而不破坏它?

Nic*_*ick 0

您可以有条件地使用它的返回值,而不是有条件地调用钩子吗?

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
  }, []);
}
Run Code Online (Sandbox Code Playgroud)