I am struggling to write SwitchContext
and/or SwitchButton
so that the SwitchButton
makes toggling between components MenuOne
and MenuTwo
happen.
I tried to put an IF ELSE
statement in SwitchContext
with a value
, and then when that value
is true
(in SwitchButton
), it would switch to MenuOne
and when false
then switch to MenuTwo
. But that did not work. How to make it?
Layout.tsx
:
<div>
<SwitchContext>
<SwitchButton />
<div><!-- switch MenuOne <> MenuTwo --></div>
</SwitchContext>
</div>
MenuOne
(and MenuTwo
is the same but with different content):
"use client";
export default function MenuOne() {
return (
<div>
<p>MenuOne</p>
<div>);}
SwitchContext.tsx
: (Question: How to write SwitchContext.tsx
so that toggling happens between component MenuOne
and MenuTwo
when clicking SwitchButton
?):
"use client";
import MenuOne from "./MenuOne";
import MenuTwo from "./MenuTwo";
import { createContext, useContext, useState } from "react";
const SwitchContext = createContext(false);
export default function SwitchContext({children,}: {children: React.ReactNode;}) {
const [switch, setSwitch] = useState(true);
const switchFunction = () => {
setSwitch(!switch);
return (
<SwitchContext.Provider value={{ switch, switchFunction }}>
{children}
</SwitchContext.Provider>
);
}
export function useSwitchContext() {
return useContext(SwitchContext);
}
SwitchButton
(Question: How to write SwitchButton.tsx
so that toggling happens between component MenuOne
and MenuTwo
when clicking SwitchButton
?):
"use client";
import MenuOne from "./MenuOne";
import MenuTwo from "./MenuTwo";
export default function Switch() {
const { switch, setSwitch } = useSwitchContext();
return (
<button type="button" onClick={() => setSwitch(!switch)}</button>
);
}
Your mindset of creating SwitchContext.tsx
is utterly correct. But I couldn't understand why you imported the MenuOne
and the MenuTwo
there!
Also, your initial value isn't aligned with your pass value, and you have a curly brace syntax mistake. I'll fix both now:
import { createContext, useContext, useState } from "react";
type SwitchContextType = {
switch: boolean;
switchFunction: () => void;
};
// Here is the initial value issue
const SwitchContext = createContext<SwitchContextType>({
switch: false,
switchFunction: () => {},
});
export default function SwitchContext({children,}: {children: React.ReactNode;}) {
const [switch, setSwitch] = useState(true);
const switchFunction = () => {
setSwitch(!switch);
}; // Here is the missed curly brace
return (
<SwitchContext.Provider value={{ switch, switchFunction }}>
{children}
</SwitchContext.Provider>
);
};
export function useSwitchContext() {
return useContext(SwitchContext);
}; // By this lovely hook, you will pass the switch and the
// switchFunction everywhere, nothing else!
And inside the switch button should be exactly like the following, not the one you wrote:
// Still here, it's not needed to import the MenuOne or MenuTwo
export default function Switch() {
const { switchFunction } = useSwitchContext();
return (
<button type="button" onClick={switchFunction}</button>
);
}
Now, it is time to toggle between the MenuOne
and the MenuTwo
:
// Layout.tsx
import MenuOne from "./MenuOne";
import MenuTwo from "./MenuTwo";
const Layout = () => {
const { switch } = useSwitchContext();
const Menu = switch ? MenuOne : MenuTwo;
return (
<>
<div>
<Menu />
</div>
</>
);
};
The above code Layout.tsx
is a sample code to show you how to use the useSwitchContext
and how to toggle between MenuOne
and MenuTwo
to render.