I have a component that requires fetching some data from a backend via a gql query.
I'm using a state object to set some keys based on the values fetched via the API.
The component either renders or doesn't by checking if the relevant key is empty or not. Initially, I was just doing it sequentially by instantiating an empty string var and then calling the API, setting the var to the result if it existed.
Thought I might instead use useState but the below code seems to give me Invalid hook call. Hooks can only be called inside of the body of a function component
. Similar stuff is being done all over the project so don't think it's some kind of version mismatch.
const SomeComponent = React.memo<PropInterface>(({ someProp }): JSX.Element => {
const [state, setState] = useState<StateObj>({
key1: '',
key2: '',
key3: '',
})
useEffect(() => {
if (someProp === someCondition) {
const { data } = useSomeQuery(args)
if (data) {
setState(prev => ({...prev, key1: data.newVal}));
}
}
}, [someProp]);
... rest of component inc two similar queries
I am doing this for 3 separate queries in the component each with a corresponding string value in the state object I have defined. I can't see what's wrong with what I am doing here, should I be using useRef instead? Wondering if it's even necessary or any benefit to using the hook in this case given that whether the component renders is dependent on retrieving something from the backend and the component is read-only so nothing is being updated, but I would prefer all queries run async to not block each other, so can just revert back to calling everything sequentially in the component to deal with this?
CodePudding user response:
You can't call hooks inside useEffect. `
const SomeComponent = React.memo<PropInterface>(({ someProp }): JSX.Element => {
const { data } = useSomeQuery(args);
//use this data object.
... rest of component inc two similar queries
`
CodePudding user response:
If you are simply looking into the data returned by your useSomeQuery
hook, then you should simply be able to use that data
element inside your template code to decide whether or not the component template should be rendered.
const SomeComponent = React<PropInterface>(({ someProp }): JSX.Element => {
const { data } = useSomeQuery(args);
// data is returned asynchronously
return (
{data.key1 ? <p>RENDER ME</p> : null}
{data.key2 ? <p>RENDER ME</p> : null}
{data.key3 ? <p>RENDER ME</p> : null}
)
}