I am looking to conditionally call useContext. This is my original code, which runs correctly, but fails tslint.
Component that calls useResourceScope - say 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
}, []);
}
Component that defines useResourceScope - say 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;
}
This gives me a tslint error: (react-hooks-nesting) A hook cannot be used in a conditional expression
This is my attempt at solving this, but does not work. It does not run correctly and fails at the useContext line in Component2 My thought was that since useContext must be called to fix the tslint errors, I decided to conditionally call the useContext with different created contexts. If the variable inputResources
is passed in, it calls useContext
with a placeholder context called PlaceHolderContext
, which it ignores and returns inputResources
. If not, it does useContext
using the intended ResourceScopeContext
value.
Component that calls useResourceScope - say 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
}, []);
}
Component that defines useResourceScope - say 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;
}
Could you suggest how I can resolve tslint error here without breaking it?
Rather than conditionally calling the hook, can you conditionally use its return value?
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
}, []);
}