Reputation: 30310
Consider two React components written in TypeScript where one is a child of the other. The child has tabs and maintains its own state as to which tab is currently selected:
export const ClientCategoryTabs: React.FunctionComponent<ClientCategoryTabsProps> = (props: ClientCategoryTabsProps) => {
const [state, setState] = useState<ClientCategoryTabsState>({
activeTab: "1"
});
...}
There are other functions that toggle tabs on click as needed. The contents of the tabs may change, and that's handled in further descendants of this tabbed child component.
Meanwhile, there are events in the parent component that need to reset the active tab to the first.
While I know that providing new props can trigger a rerender, I can't figure out how to trigger a reset of the child state (well, just the tabs not the data inside the tabs) without leaking that state to the parent--in other words, maintaining the active tab state in the parent and then initializing child state with that value.
Any ideas on how to maintain that separation are appreciated.
Upvotes: 0
Views: 1576
Reputation: 7991
You can add a prop to the tab container that sets the active tab from outside:
<CategoryTabContainer activeTab={1} />
const CategoryTabContainer : React.FC<ClientCategoryTabsProps> = ({ activeTab = 1 }) => {
const [activeTabValue, setActiveTabValue] = useState<number>(activeTab);
// synchronize props with state
useEffect(() => {
if (activeTab !== activeTabValue) {
setActiveTabValue(activeTab);
}
}, [activeTab]);
// ...
}
Then, set the logic for reset state in parent component.
On the other hand, would you consider using ContainerTabContainer
for rendering and using hooks to for setting the state?
const [activeTab, onTabClick, setActiveTab] = useTabs(tabData);
return (
<>
<button onClick={() => setActiveTab(0)}>Reset</button>
<CategoryTabContainer activeTab={activeTab} onTabClick={onTabClick} />
</>
);
I personally prefer this approach more as it is more direct and "Reacty" :)
Upvotes: 1