Last active
May 16, 2018 09:41
-
-
Save dariocravero/54ef54aa7116338c28088cc89bc2197f to your computer and use it in GitHub Desktop.
A POC of a User/Auth context provider for React apps
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 UserContext = React.createContext({}) | |
export const Consumer = Context.Consumer | |
export class Provider extends React.Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
token: getToken(props.token), | |
login: this.login, | |
logout: this.logout, | |
data: null, | |
} | |
} | |
static getDerivedStateFromProps(nextProps, prevState) { | |
if (nextProps.token && nextProps.token !== prevState.token) { | |
return { | |
token: nextProps.token, | |
data: null, | |
} | |
} | |
return null | |
} | |
componentDidMount() { | |
this.getUser() | |
} | |
componentDidUpdate() { | |
if (this.state.token !== prevState.token) { | |
this.getUser() | |
} | |
} | |
getUser = async () => { | |
if (this.state.token) { | |
this.setState({ data: await getUser(this.state.token) }) | |
} | |
} | |
login = async ({ user, password }) => { | |
// do login stuff | |
const token = await login({ user, password }) | |
if (token) { | |
this.setState({ | |
token, | |
}) | |
} | |
} | |
logout = () => { | |
// clear token | |
logout() | |
this.setState({ token: null, data: null }) | |
} | |
render() { | |
return ( | |
<UserContext.Provider value={this.state}> | |
{props.children} | |
</UserContext.Provider> | |
) | |
} | |
} | |
// ... at point of use ... | |
import * as User from './User.js' | |
const UserName = props => ( | |
<User.Consumer>{user => <div>{user.data.name}</div>}</User.Consumer> | |
) | |
const LoginOrLogout = props => ( | |
<User.Consumer> | |
{user => | |
user.token ? ( | |
<div onClick={user.logout}>logout</div> | |
) : ( | |
<div onClick={user.login}>login</div> | |
) | |
} | |
</User.Consumer> | |
) | |
// ... somewhere before all the stuff above is used ... | |
import * as User from './User.js' | |
const App = props => ( | |
<User.Provider> | |
<UserName /> <LoginOrLogout />{' '} | |
</User.Provider> | |
) |
[brain dump from an internal conversation]
What happens if a part of the app needs the user but not the environment?
What happens if, say, your app stops using the environment altogether, how do you know when you can delete that loader?
In that solution, the state is held in a global store. Say you want to have a part of the app that works as if it were another user (which is a use case in Ed). How do you get to work under a different environment or impersonate a user?
In the contextual user API from above you could do something like the nested users above.
Any consumer of the app will use the second user in that subset of the app down below.
Another aspect of it is, what happens to your user if you decide to stop using sagas or redux?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nested users?