Skip to content

Instantly share code, notes, and snippets.

@MaximeHeckel
Last active April 6, 2022 22:11
Show Gist options
  • Save MaximeHeckel/8c1ada76826e7b34fc690b2f7357c9ac to your computer and use it in GitHub Desktop.
Save MaximeHeckel/8c1ada76826e7b34fc690b2f7357c9ac to your computer and use it in GitHub Desktop.
Example of App replacing Redux with Context and Hooks
// 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