Skip to content

Instantly share code, notes, and snippets.

@alfrcr
Last active August 17, 2018 17:21
Show Gist options
  • Select an option

  • Save alfrcr/86663b522285fcc05b98a454c1918cd2 to your computer and use it in GitHub Desktop.

Select an option

Save alfrcr/86663b522285fcc05b98a454c1918cd2 to your computer and use it in GitHub Desktop.
Build a Redux-like with React Context
import React from "react";
import get from "lodash/get";
import { withUser, actions } from "./user-context";
class Home extends React.Component {
authenticate = () => {
this.props.dispatch(actions.mockAsyncLogin());
};
render() {
const { user, loading } = this.props;
if (loading) {
return <h1>Loading...</h1>;
}
return (
<div className="App">
<h1>
{user.isAuth ? `Hi, ${get(user, "data.name", "")}` : "Please login"}
</h1>
<h2>React Context FTW!</h2>
<div>
<button onClick={this.authenticate}>Login</button>
</div>
</div>
);
}
}
export default withUser(Home);
import React from "react";
import ReactDOM from "react-dom";
import { UserProvider } from "./user-context";
import Home from "./Home";
import "./styles.css";
function App() {
return (
<UserProvider>
<Home />
</UserProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React from "react";
const { Provider, Consumer } = React.createContext({
loading: false,
data: null,
isAuth: false,
dispatch: () => {}
});
export const types = {
AUTHENTICATE: "AUTHENTICATE",
AUTHENTICATION_SUCCESS: "AUTHENTICATION_SUCCESS"
};
export const actions = {
mockAsyncLogin: () => {
return dispatch => {
dispatch({
type: types.AUTHENTICATE
});
// Ceritanya disini lagi fetch API auth
setTimeout(() => {
dispatch({
type: types.AUTHENTICATION_SUCCESS,
payload: {
name: "Deby Octaviani"
}
});
}, 1500);
};
}
};
export class UserProvider extends React.Component {
reducer = (state, action) => {
switch (action.type) {
case types.AUTHENTICATE:
return {
...state,
loading: true
};
case types.AUTHENTICATION_SUCCESS:
return {
...state,
loading: false,
data: action.payload,
isAuth: true
};
default:
return state;
}
};
dispatch = action => {
if (typeof action === "function") {
return action(this.dispatch);
}
this.setState(prevState => {
return this.reducer(prevState, action);
});
};
state = {
loading: false,
data: null,
isAuth: false,
dispatch: this.dispatch
};
render() {
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
export function withUser(Component) {
return function WrappedComponent(props) {
return (
<Consumer>
{({ dispatch, loading, ...rest }) => (
<Component loading={loading} user={rest} dispatch={dispatch} />
)}
</Consumer>
);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment