Last active
May 28, 2022 09:39
-
-
Save mfrancois3k/4cc4d20431a5a7bec3cf45cc7befacd2 to your computer and use it in GitHub Desktop.
useReducer and Context Together
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
store > global > CombinedContextProviders.js | |
//https://codesandbox.io/s/how-to-use-contex-use-reducer-use-memo-forked-zf1k65?file=/src/components/DisplayAuth.js:0-472 | |
import ContextProviderComposer from "./ContextProviderComposer"; | |
import { GlobalStateProvider } from "./global/global.provider"; | |
const CombinedContextProviders = ({ children }) => { | |
return ( | |
<ContextProviderComposer | |
contextProviders={[<GlobalStateProvider key={"global_state_provider"} />]} | |
> | |
{children} | |
</ContextProviderComposer> | |
); | |
}; | |
export default CombinedContextProviders; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
store > global > ContextProviderComposer.js | |
import React from "react"; | |
const ContextProviderComposer = ({ contextProviders, children }) => { | |
return contextProviders.reduceRight( | |
(children, parent) => React.cloneElement(parent, { children }), | |
children | |
); | |
}; | |
export default ContextProviderComposer; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useContext } from "react"; | |
import { GlobalState } from "../store/global/global.state"; | |
const DisplayAuth = () => { | |
console.log("re-render subcomponent"); | |
const { isLoggedIn, login, logout } = useContext(GlobalState); | |
return ( | |
<> | |
<div className="App">{isLoggedIn ? "Welcome back" : "Please login"}</div> | |
<button onClick={login}> Login </button> | |
<button onClick={logout}> Logout </button> | |
</> | |
); | |
}; | |
export default DisplayAuth; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
store > global > globalsState.js | |
import { useReducer, createContext } from "react"; | |
// Define the initial state | |
const GLOBAL_STATE = { | |
isLoggedIn: undefined, | |
theme: "light", | |
isModalOpen: false, | |
pageBuilder: [], | |
create, | |
delete, | |
update | |
}; | |
// Define the reducer | |
const globalReducer = (state, action) => { | |
switch (action.type) { | |
case "LOGIN": | |
return { | |
...state, | |
isLoggedIn: true | |
}; | |
case "LOGOUT": | |
return { | |
...state, | |
isLoggedIn: false | |
}; | |
case "LIGHT_THEME": | |
return { | |
...state, | |
theme: "light" | |
}; | |
case "DARK_THEME": | |
return { | |
...state, | |
theme: "dark" | |
}; | |
case "OPEN_MODAL": | |
return { | |
...state, | |
isModalOpen: true | |
}; | |
case "CLOSE_MODAL": | |
return { | |
...state, | |
isModalOpen: false | |
}; | |
case "CREATE_BUILDER": | |
return { | |
...state, | |
pageBuilder: { | |
...state.pageBuilder, | |
[action.payload.key]: action.payload | |
} | |
}; | |
case "DELETE_BUILDER": | |
return { | |
...state, | |
pageBuilder: state.pageBuilder.filter( | |
(builder) => builder._id !== action.payload | |
), | |
loading: false | |
}; | |
case "UPDATE_BUILDER": | |
return { | |
...state, | |
pageBuilder: { | |
...state.pageBuilder, | |
[action.payload.key]: action.payload | |
} | |
}; | |
default: | |
return state; | |
} | |
}; | |
// Create the context | |
export const GlobalState = createContext(); | |
GlobalState.displayName = "GlobalState"; | |
export const GlobalStateProvider = ({ children }) => { | |
// Create the reducer | |
const [state, dispatch] = useReducer(globalReducer, GLOBAL_STATE); | |
const value = { | |
...state, | |
login: () => { | |
dispatch({ type: "LOGIN" }); | |
}, | |
logout: () => { | |
dispatch({ type: "LOGOUT" }); | |
}, | |
setLightTheme: () => { | |
dispatch({ type: "LIGHT_THEME" }); | |
}, | |
setDarkTheme: () => { | |
dispatch({ type: "DARK_THEME" }); | |
}, | |
openModal: () => { | |
dispatch({ type: "OPEN_MODAL" }); | |
}, | |
closeModal: () => { | |
dispatch({ type: "CLOSE_MODAL" }); | |
}, | |
create_builder: () => { | |
dispatch({ type: "CREATE_BUILDER" }); | |
}, | |
delete_builder: () => { | |
dispatch({ type: "DELETE_BUILDER" }); | |
}, | |
update_builder: () => { | |
dispatch({ type: "UPDATE_BUILDER" }); | |
} | |
}; | |
// Wrap the context provider around our component | |
return <GlobalState.Provider value={value}>{children}</GlobalState.Provider>; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// import { StrictMode } from "react"; | |
import { createRoot } from "react-dom/client"; | |
import App from "./App"; | |
import CombinedContextProviders from "./store/CombinedContextProviders"; | |
// import { GlobalStateProvider } from "./store/global/global.provider"; | |
const rootElement = document.getElementById("root"); | |
const root = createRoot(rootElement); | |
root.render( | |
// <GlobalStateProvider> | |
<CombinedContextProviders> | |
<App /> | |
</CombinedContextProviders> | |
// </GlobalStateProvider> | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/ import { useContext } from "react"; | |
import DisplayAuth from "./components/DisplayAuth"; | |
// import { GlobalState } from "./store/global/global.state"; | |
import "./styles.css"; | |
export default function App() { | |
console.log("re-render root app"); | |
// const { isLoggedIn, login, logout } = useContext(GlobalState); | |
return ( | |
<> | |
<DisplayAuth /> | |
{/* <div className="App">{isLoggedIn ? "Welcome back" : "Please login"}</div> */} | |
{/* <button onClick={login}> Login </button> | |
<button onClick={logout}> Logout </button> */} | |
</> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment