Last active
April 6, 2022 22:11
-
-
Save MaximeHeckel/8c1ada76826e7b34fc690b2f7357c9ac to your computer and use it in GitHub Desktop.
Example of App replacing Redux with Context and Hooks
This file contains 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
// reducer.js | |
export const initialState = { | |
data: null | |
}; | |
const reducer = (state, action) => { | |
const reduced = { ...state }; | |
switch (action.type) { | |
case "FETCH_DATA": | |
return { | |
...reduced, | |
data: action.payload | |
}; | |
case "RESET_DATA": | |
return initialState; | |
default: | |
return state; | |
} | |
}; | |
export default reducer; | |
// store.js | |
import React, { createContext, useReducer } from "react"; | |
import reducer, { initialState } from "./reducer"; | |
const Store = createContext(); | |
const Provider = ({ children }) => { | |
const [state, dispatch] = useReducer(reducer, initialState); | |
const value = { state, dispatch }; | |
return <Store.Provider value={value}>{children}</Store.Provider>; | |
}; | |
const connect = ( | |
mapStateToProps = () => {}, | |
mapDispatchToProps = () => {} | |
) => WrappedComponent => { | |
return props => { | |
const { dispatch, state } = useContext(Store); | |
return ( | |
<WrappedComponent | |
dispatch={dispatch} | |
{...mapStateToProps(state, props)} | |
{...mapDispatchToProps(dispatch)} | |
/> | |
); | |
}; | |
}; | |
export { Store, Provider, connect }; | |
// App.js | |
import React, { useContext, useEffect } from "react"; | |
import { Store, Provider, connect } from "./store"; | |
import logo from "./logo.svg"; | |
import "./App.css"; | |
const mapStateToProps = (state, props) => ({ | |
message: `${state.data} ${props.extra}` | |
}); | |
const mapDispatchToProps = dispatch => ({ | |
sendMsg: () => dispatch({ type: "RESET_DATA", payload: "null" }) | |
}); | |
const Data = props => { | |
return ( | |
<div> | |
{props.message} | |
<button onClick={() => props.sendMsg()}> | |
Reset From MapDispatchToProps Function | |
</button> | |
</div> | |
); | |
}; | |
const ConnectedData = connect( | |
mapStateToProps, | |
mapDispatchToProps | |
)(Data); | |
const Controls = () => { | |
const { state, dispatch } = useContext(Store); | |
useEffect(() => { | |
if (!state.data) { | |
dispatch({ type: "FETCH_DATA", payload: "Ready!" }); | |
} | |
}); | |
return ( | |
<div> | |
<button | |
onClick={() => | |
dispatch({ type: "FETCH_DATA", payload: "Hello world!" }) | |
} | |
> | |
Fetch Data | |
</button> | |
<button onClick={() => dispatch({ type: "RESET_DATA", payload: null })}> | |
Reset | |
</button> | |
</div> | |
); | |
}; | |
const App = () => { | |
return ( | |
<div className="App"> | |
<Provider> | |
{/* This is an equivalent to the react-redux Provider component */} | |
<header className="App-header"> | |
<img src={logo} className="App-logo" alt="logo" /> | |
<h1>React {React.version}</h1> | |
<Controls /> | |
<ConnectedData extra="TEST" /> | |
</header> | |
</Provider> | |
</div> | |
); | |
}; | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment