Skip to content

Instantly share code, notes, and snippets.

@mskoroglu
Created November 7, 2019 20:40
Show Gist options
  • Save mskoroglu/172a07cbd05c6962a8391f35750564c6 to your computer and use it in GitHub Desktop.
Save mskoroglu/172a07cbd05c6962a8391f35750564c6 to your computer and use it in GitHub Desktop.
import React from "react";
import { withState, multiState } from "./multi-state";
const Input = ({ state, ...props }) => (
<input
value={state.value}
onChange={e => state.setValue(e.target.value)}
{...props}
/>
);
const StatefulInput = withState(Input);
const App = () => {
const state = multiState({
name: "John",
surname: "Doe",
favoriteFruit: "Banana"
});
const fruits = ["Apple", "Banana", "Orange"];
return (
<div>
<StatefulInput state={state.nameState()} />
<StatefulInput
state={state.surnameState()}
style={{ display: "block", marginTop: ".5rem" }}
/>
<select
value={state.favoriteFruit}
onChange={e => state.setFavoriteFruit(e.target.value)}
style={{ marginTop: ".5rem" }}
>
{fruits.map((fruit, i) => (
<option key={i}>{fruit}</option>
))}
</select>
<pre>{JSON.stringify(state, null, 2)}</pre>
<FooForm />
</div>
);
};
const FooForm = () => {
const { email, setEmail, password, ...state } = multiState({
id: 1,
email: null,
password: "s3cret"
});
return (
<ul>
<li>id: {state.id}</li>
<li>
email: {email} &mdash;
<button onClick={() => setEmail("foo@bar.baz")}>change</button>
</li>
<li>password: {password}</li>
</ul>
);
};
import React from "react";
export const multiState = map =>
Object.keys(map).reduce((state, key) => {
const [value, setValue] = React.useState(map[key]);
const setter = "set" + key.charAt(0).toUpperCase() + key.slice(1);
const fnName = key + "State";
return Object.assign(state, {
[key]: value,
[setter]: setValue,
[fnName]: () => ({ value, setValue })
});
}, {});
export const withState = Component => ({ state, ...props }) => (
<Component state={state} {...props} />
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment