I am new to React. I am making an app using AntD-mobile. For Bottom navigation, I am making use of the tabBar Component in AntD-mobile. I was not sure how to use Link
for routing with TabBar and after a lot of failed attempts, came upon useNavigate
.
const [navLink, setNavLink] = React.useState("/");
const navigate = useNavigate();
const redirect = useCallback(() => navigate(navLink, {replace: true}), [navigate]);
I want to redirect to whichever tab is clicked upon, for that, I used State, TabBar's onChange changes the state first and calls redirect. But for some reason, the previous state is loaded. If I am on state 1 and click 2, it stays on 1, When I click 4, it goes to 2 and so on. So probably, the redirect is loading ahead of state change. -
<TabBar onChange={(key)=>{setNavLink(key); redirect();}}>
{tabs.map(item => (
<TabBar.Item key={item.key} icon={item.icon} title={item.title}>
</TabBar.Item>
))}
</TabBar>
To solve, this I tried using useEffect()
, wherein I change only the state in TabBar's onChange and call redirect inside useEffect. But this doesn't work. redirect is not working.
useEffect(() => {
redirect()
}, [navLink]);
What am I doing wrong? How to set bottom navigation in the tabBar?
The original code didn't work because both setNavLink(key);
and redirect();
happen in the same render cycle. When redirect
is called the enqueued state update hasn't been processed yet, so it's still the previous state's value.
onChange={(key) => {
setNavLink(key); // <-- enqueued state update
redirect(); // <-- navLink state not updated yet!
}}
The redirect
function is missing a dependency, adding navLink
to the dependency array will re-enclose the updated navLink
state value. useCallback(() => navigate(navLink, {replace: true}), [navigate]);
only computes/recomputes the callback on the initial render or when the dependencies update.
const redirect = useCallback(
() => navigate(navLink, { replace: true }),
[navigate, navLink]
);
useEffect(() => {
redirect()
}, [redirect]);
...
onChange={setNavLink}
You can pass the navLink
state in as an argument.
const redirect = useCallback(
(navLink) => navigate(navLink, { replace: true }),
[navigate]
);
useEffect(() => {
redirect(navLink);
}, [navLink, redirect]);
...
onChange={setNavLink}
Or you can just use navigate
directly in the useEffect
when the navLink
state updates.
useEffect(() => {
navigate(navLink, { replace: true });
}, [navLink]);
...
onChange={setNavLink}
Or just navigate directly in the onChange
handler.
<TabBar onChange={(navLink) => navigate(navLink, { replace: true })}>
{tabs.map(item => (
<TabBar.Item
key={item.key}
icon={item.icon}
title={item.title}
/>
))}
</TabBar>