Last active
August 17, 2018 17:21
-
-
Save alfrcr/86663b522285fcc05b98a454c1918cd2 to your computer and use it in GitHub Desktop.
Build a Redux-like with React Context
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 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); |
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 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); |
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 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