T
TanStack•4y ago
sensitive-blue

How to manage 'data is undefined'

I am working on a migration from redux to RQ. Our existing codebase is full of useEffect's which RQ is slowly replacing which is great, however, there are some instances where the app is breaking as the data is rendering as undefined but useEffect is expecting the value ( I agree we are using useEffect incorrectly probably but maybe there is a fix?). An example is that we logout a user if they are not authenticated on a particular journey. However, a user may indeed be authenticated but the value is undefined so considered falsy.
const { data: userData } = fetchUser();

const isAuthenticated = userData?.is_authenticated; // undefined on mount and I understand why it happens.

useEffect(() => {
if (!isAuthenticated) {
history.push('navigated');
}
}, [isAuthenticated]);
const { data: userData } = fetchUser();

const isAuthenticated = userData?.is_authenticated; // undefined on mount and I understand why it happens.

useEffect(() => {
if (!isAuthenticated) {
history.push('navigated');
}
}, [isAuthenticated]);
5 Replies
foreign-sapphire
foreign-sapphire•4y ago
Maybe you could use isLoading provided by react query to distinguish case when there's no data vs data is not fetched yet?
quickest-silver
quickest-silver•4y ago
I'd just change the condition to:
if (isAuthenticated === false)
if (isAuthenticated === false)
to exclude the undefined value
sensitive-blue
sensitive-blueOP•4y ago
Yes that is what I was thinking. I will do some testing tomorrow morning. Does your suggestion @TkDodo 🔮 take into consideration the useEffect?
quickest-silver
quickest-silver•4y ago
not sure what you mean. first, the effect will run with undefined and "do nothing", then, it will run again with false and redirect. note that your component will still render with isAuthenticated: false, so maybe the better idea is to do a a <Redirect> via a component. Given that you're using react-router:
const userQuery = useUserQuery()

if (userQuery.isLoading) return <LoadingSpinner />

// we can now do the simple boolean check because isLoading excludes undefined data already
if (!userQuery.data) return <Redirect to='/navigated' />

return <HereGoesTheAuthenticatedApp user={userQuery.data} />
const userQuery = useUserQuery()

if (userQuery.isLoading) return <LoadingSpinner />

// we can now do the simple boolean check because isLoading excludes undefined data already
if (!userQuery.data) return <Redirect to='/navigated' />

return <HereGoesTheAuthenticatedApp user={userQuery.data} />
sensitive-blue
sensitive-blueOP•4y ago
Works a charm. Thanks @TkDodo 🔮 🤩

Did you find this page helpful?