I'm trying to understand the useTransition hook by reading the official React documentation. In the documentation, there is a "SelectTab" example with different versions, but the result is the same.
Case 1:
import { useState, useTransition } from 'react';
import TabButton from './TabButton.js';
import AboutTab from './AboutTab.js';
import PostsTab from './PostsTab.js';
import ContactTab from './ContactTab.js';
export default function TabContainer() {
const [isPending, startTransition] = useTransition();
const [tab, setTab] = useState('about');
function selectTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
return (
<>
<TabButton
isActive={tab === 'about'}
onClick={() => selectTab('about')}
>
About
</TabButton>
<TabButton
isActive={tab === 'posts'}
onClick={() => selectTab('posts')}
>
Posts (slow)
</TabButton>
<TabButton
isActive={tab === 'contact'}
onClick={() => selectTab('contact')}
>
Contact
</TabButton>
<hr />
{tab === 'about' && <AboutTab />}
{tab === 'posts' && <PostsTab />}
{tab === 'contact' && <ContactTab />}
</>
);
}
import { useTransition } from 'react';
export default function TabButton({ children, isActive, onClick }) {
if (isActive) {
return <b>{children}</b>
}
return (
<button onClick={() => {
onClick();
}}>
{children}
</button>
)
}
Case 2:
import { useState } from 'react';
import TabButton from './TabButton.js';
import AboutTab from './AboutTab.js';
import PostsTab from './PostsTab.js';
import ContactTab from './ContactTab.js';
export default function TabContainer() {
const [tab, setTab] = useState('about');
return (
<>
<TabButton
isActive={tab === 'about'}
onClick={() => setTab('about')}
>
About
</TabButton>
<TabButton
isActive={tab === 'posts'}
onClick={() => setTab('posts')}
>
Posts (slow)
</TabButton>
<TabButton
isActive={tab === 'contact'}
onClick={() => setTab('contact')}
>
Contact
</TabButton>
<hr />
{tab === 'about' && <AboutTab />}
{tab === 'posts' && <PostsTab />}
{tab === 'contact' && <ContactTab />}
</>
);
}
import { useTransition } from 'react';
export default function TabButton({ children, isActive, onClick }) {
const [isPending, startTransition] = useTransition();
if (isActive) {
return <b>{children}</b>
}
if (isPending) {
return <b className="pending">{children}</b>;
}
return (
<button onClick={() => {
startTransition(() => {
onClick();
});
}}>
{children}
</button>
);
}
The output is the same for both cases. These two cases works the same. The difference between them is that clicking “Posts” now feels more responsive in case2 because of just using isPending flag. But how? Can you explain, please? Thank you!
Here are links:
Case 1: https://react.dev/reference/react/useTransition#updating-the-parent-component-in-a-transition