Long question please be ready
I've been working with react-query recently and discovered that a lot of the code has to be duplicated for every component that is using useQuery. For example:
if(query.isLoading) {
return 'Loading..'
}
if(query.isError) {
return 'Error'
}
if(query.isSuccess) {
return 'YOUR ACTUAL COMPONENT'
}
I tried creating a wrapper component to which you pass in the query information and it will handle all the states for you.
A basic implementation goes as follows:
const Wrapper = ({ query, LoadingComponent, ErrorComponent, children }) => {
if (query.isLoading) {
const toRender = LoadingComponent || <DefaultLoader />;
return <div className="grid place-items-center">{toRender}</div>;
}
if (query.isError) {
const toRender = ErrorComponent ? (
<ErrorComponent />
) : (
<div className="dark:text-white">Failed to Load</div>
);
return <div className="grid place-items-center">{toRender}</div>;
}
if (query.isSuccess) {
return React.Children.only(children);
}
return null;
};
And, using it like:
const Main = () => {
const query = useQuery(...);
return (
<Wrapper query={query}>
<div>{query.message}</div>
</Wrapper>
)
}
The issue with this is that query.message can be undefined and therefore throws an error. Can't read property message of undefined
But, it should be fixable by optional chaining query?.message.
This is where my confusion arises. The UI elements inside wrapper should have been rendered but they donot. And, if they don't then why does it throw an error.
This means that, the chilren of wrapper are executed on each render. But not visible. WHY??
Render Props to rescue
Wrapper
const WrapperWithRP = ({ query, children }) => {
const { isLoading, data, isError, error } = query;
if (isLoading) return 'Loading...'
if (isError) return 'Error: ' + error
return children(data)
}
And using it like,
const Main = () => {
const query = useQuery(...);
return (
<Wrapper query={query}>
{state => {
return (
<div>{query.message}</div>
)
}
}
</Wrapper>
)
}
This works as expected. And the children are only rendered when the state is either not loading or error.
I am still confused as to why the first approach doesn't show the elements on the UI event when they are clearly executed?
Codesandbox link replicating the behaviour: https://codesandbox.io/s/react-composition-and-render-prop-tyyzh?file=/src/App.js
Aucun commentaire:
Enregistrer un commentaire