Skip to content

Instantly share code, notes, and snippets.

@alexkrolick
Last active January 24, 2018 05:45
Show Gist options
  • Save alexkrolick/3b06bbe2821c1adee090518aa177ebb0 to your computer and use it in GitHub Desktop.
Save alexkrolick/3b06bbe2821c1adee090518aa177ebb0 to your computer and use it in GitHub Desktop.
Redux-like reducer using just setState
const api = {
fetchUser(id) {
return { id, name: "username" };
}
};
class UserState extends React.Component {
state = {
user: null,
signinCount: 0,
apiErr: false
};
reducer = {
"user:login": async id => {
let data;
try {
data = await api.fetchUser(id);
} catch (err) {
return { apiErr: true };
}
return state => ({
user: data,
signinCount: state.signinCount + 1
});
},
"user:logout": () => {
return state => ({
user: null
});
}
};
defaultAction = () => null;
dispatch = async (type, payload) => {
const handler = this.reducer[type] || this.defaultAction;
const handlerResult = await handler(payload);
const result = await new Promise(resolve => {
this.setState(handlerResult, resolve);
});
};
actions = Object.keys(this.reducer);
render() {
const { props, state, dispatch, actions } = this;
const signedIn = state.user !== null;
let button;
if (signedIn)
button = <button onClick={() => dispatch("user:logout")}>Logout</button>;
else
button = (
<button onClick={() => dispatch("user:login", props.userId)}>
Login
</button>
);
return (
<div>
<p>
Signed in {state.signinCount} times.
</p>
<p>
{ signedIn ? `Hello ${state.user.name}` : '' }
</p>
{ button }
</div>
);
}
}
ReactDOM.render(<UserState userId={1} />, document.querySelector(".app"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment