I have two custom React hooks that fetch different data and parse it. Both hooks return an object of the same type. I have a component that displays that data and depending on a "variant" prop, i want it to decide which of those two hooks it mounts.
Example code:
const useJohn = () => {
// fetch & parse some data
return { parsedData: { date: new Date(), name: 'John Doe' } }
}
const useJane = () => {
// fetch & parse some data
return { parsedData: { date: new Date(), name: 'Jane Smith' } }
}
const dataDisplay = ({ variant }: { variant: 'John' | 'Jane' }) => {
const hook = variant === 'John' ? useJohn : useJane
const { parsedData } = hook()
return <div>{`${parsedData.date.toString()} ${parsedData.name}`}</div>
}
I get no warnings/errors from this pattern and everything seems to be working fine. Is this a legitimate way of conditionally using custom hooks? Or are there any issues with this pattern that i am not aware of?
If you want conditionally use a hook, use the condition in its implementation.
Please check the accepted post here use the condition in its implementation.
Please see below your code refactored on the same basis. The test run results have also been enclosed.
App.js
import { useEffect, useState } from 'react';
export default function App() {
const [variant, setVariant] = useState('John');
useEffect(() => {
setTimeout(() => setVariant('Jane'), 5000);
}, []);
return (
<>
<DataDisplay variant={variant} />
</>
);
}
const useJohn = (variant) => {
if (variant === 'John') {
// fetch & parse some data
return { parsedData: { date: new Date(), name: 'John Doe' } };
} else {
return null;
}
};
const useJane = (variant) => {
if (variant === 'Jane') {
// fetch & parse some data
return { parsedData: { date: new Date(), name: 'Jane Smith' } };
} else {
return null;
}
};
const DataDisplay = ({ variant }) => {
const parsedDataJohn = useJohn(variant);
const parsedDataJane = useJane(variant);
const { parsedData } = parsedDataJohn ? parsedDataJohn : parsedDataJane;
return <div>{`${parsedData.date.toString()} ${parsedData.name}`}</div>;
};