//!!!!! JavaScript Solution - For TypeScript visit my profile
/* Implement React ContextAPI using the complex way
and use it to the calmy way.
Optional COOKIE feature added (npm i universal-cookie)*/
//** First thing first create a provider component
//** π StateProvider.js (.jsx)
import * as React from "react";
/*import Cookies from "universal-cookie";
const cookies = new Cookies();
const CookieExpiry = (props) => {
const { interval, intervalBy } = props; // Here interval variable is holding the period and intervalBy variable holding the unit (eg. millisecond, second, munite, hour, day, month and year)
let expire = new Date();
if (intervalBy === "ms") {
expire.setMilliseconds(expire.getMilliseconds() + interval);
} else if (intervalBy === "s") {
expire.setSeconds(expire.getSeconds() + interval);
} else if (intervalBy === "m") {
expire.setMinutes(expire.getMinutes() + interval);
} else if (intervalBy === "h") {
expire.setHours(expire.getHours() + interval);
} else if (intervalBy === "d") {
expire.setDate(expire.getDate() + interval);
} else if (intervalBy === "mo") {
expire.setMonth(expire.getMonth() + interval);
} else if (intervalBy === "y") {
expire.setFullYear(expire.getFullYear() + interval);
}
return expire;
};
const cookieOptions = {
path: "/",
expires: CookieExpiry({ interval: 1, intervalBy: "y" }),
maxAge: (CookieExpiry({ interval: 1, intervalBy: "y" }).getTime() - new Date().getTime()) / 1000,
secure: true, //if you are on localhost set it to - false
httpOnly: true, //if you are on localhost set it to - false
sameSite: true, //value can be changed to - Lax, None, Strict
};*/ //(Uncomment if you're adding cookie Feature)
const ModeContextDefaultValue = {
mode: "light", // (comment it if you're adding cookie Feature)
//mode: cookies.get("mode") === undefined ? "light" : cookies.get("mode"), //(Uncomment if you're adding cookie Feature)
changeMode: () => {},
};
export const ModeContext = React.createContext(ModeContextDefaultValue);
const StateProvider = ({children}) => {
// this state will be shared with all components
const [mode, setMode] = React.useState(ModeContextDefaultValue.mode);
const changeMode = (newMode) => {
//cookies.set("mode", newMode, cookieOptions); //(Uncomment if you're adding cookie Feature)
setMode(newMode);
};
return(
// this is the provider providing state
<ModeContext.Provider value={{ mode, changeMode }}>
{children}
</ModeContext.Provider>
);
}
export default StateProvider;
//** End of π StateProvider.js (.jsx)
/* *** We created and modified our provider, now our second work is to add
or call this provider into the root file of our project, maximum time our
root file is called App.js (.jsx). Let's create it or modife existing one!*/
//** π App.js (.jsx)
import * as React from "react";
import StateProvider from "./StateProvider"; //Path to your StateProvider.js (.jsx) file
import Index from "./Index"; //Path to you Index Component you can import any component.
const App = () => {
return(
<StateProvider>
<Index />
// Define Every single component where you want to access states that is defined into StateProvider.
</StateProvider>
);
}
export default App;
//** End of π App.js (.jsx)
/* In above steps we created and modified our provider and then we
impliment or you can say initialized our provider into root file of
our project. Now we are ready to access our states that is defined
into our provider from any component that is defined or call inside
App's StateProvider Block. Currently for testing purpose we added - Index
component into StateProvider Block of App file. So technically we can
access all the states defined into provider from Index component. Let's
see how we can do it.*/
//** π Index.jsx (.js)
import * as React from "react";
import { ModeContext } from "./StateProvider";
const Index = () => {
//const { mode } = React.useContext(ModeContext); // Uncomment if you are only accessing the state and don't want to update the state.
//const { changeMode } = React.useContext(ModeContext); // Uncomment if you are only updating the state and don't want to access the state.
const { mode, changeMode } = React.useContext(ModeContext); // we are using this because we are accessing the state and want to update this state at the same time or same component.
const updateMode = (event) => {
changeMode(event.target.value); // If you added the cookie feature this one call will also set cookie for you no additioan work needed.
//console.log(event.target.value); //see update on log
}
return (
<React.Fragment>
<h1>Current display color mode is set to {mode}</h1>
<div>
<h6>Play with it</h6>
<div onChange={updateMode}>
<input type="radio" value="light" name="mode" checked={mode === "light"} /> Light
<input type="radio" value="dark" name="mode" checked={mode === "dark"}/> Dark
</div>
</div>
</React.Fragment>
);
}
//** End of π Index.jsx (.js)