Last active
May 15, 2020 07:49
-
-
Save bfollington/e287ab3f95e121dc94f4c1981a9bc1a6 to your computer and use it in GitHub Desktop.
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, { ChangeEvent } from "react"; | |
import "./App.css"; | |
import { RecoilRoot, atom, useRecoilState } from "recoil"; | |
const useRecoilReducer = <S, A>( | |
reducer: (s: S, a: A) => S, | |
recoilState: any | |
) => { | |
const [state, setState] = useRecoilState(recoilState); | |
const dispatch = (a: A) => { | |
setState(reducer(state, a)); | |
}; | |
return [state, dispatch]; | |
}; | |
type Alignment = | |
| "lawful good" | |
| "lawful neutral" | |
| "lawful evil" | |
| "neutral good" | |
| "true neutral" | |
| "neutral evil" | |
| "chaotic good" | |
| "chaotic neutral" | |
| "chaotic evil"; | |
type ComplexState = { | |
name: string; | |
age: number; | |
alignment: Alignment; | |
}; | |
type Action = | |
| { type: "got_older" } | |
| { type: "changed_name"; payload: string } | |
| { type: "alignment_shift"; payload: Alignment }; | |
const complexDemoState = atom({ | |
key: "complexDemoState", | |
default: { | |
name: "", | |
age: 0, | |
alignment: "chaotic neutral", | |
}, | |
}); | |
const complexDemoReducer = ( | |
state: ComplexState, | |
action: Action | |
): ComplexState => { | |
switch (action.type) { | |
case "changed_name": | |
return { | |
...state, | |
name: action.payload, | |
}; | |
case "got_older": | |
return { | |
...state, | |
age: state.age + 1, | |
}; | |
case "alignment_shift": | |
return { | |
...state, | |
alignment: action.payload, | |
}; | |
default: | |
return state; | |
} | |
}; | |
const ComplexDemo = () => { | |
const [state, dispatch] = useRecoilReducer( | |
complexDemoReducer, | |
complexDemoState | |
); | |
const [name, setName] = React.useState(""); | |
const [alignment, setAlignment] = React.useState<Alignment>( | |
"chaotic neutral" | |
); | |
return ( | |
<div> | |
<label>Complex Demo</label> | |
<table> | |
<tbody> | |
<tr> | |
<td>{state.name}</td> | |
</tr> | |
<tr> | |
<td>{state.age}</td> | |
</tr> | |
<tr> | |
<td>{state.alignment}</td> | |
</tr> | |
</tbody> | |
</table> | |
<button type="button" onClick={() => dispatch({ type: "got_older" })}> | |
Get Older | |
</button> | |
<br /> | |
<input | |
type="text" | |
onChange={(e) => setName(e.target.value)} | |
value={name} | |
/> | |
<button | |
type="button" | |
onClick={() => dispatch({ type: "changed_name", payload: name })} | |
> | |
Change Name | |
</button> | |
<br /> | |
<select | |
onChange={(e) => setAlignment(e.target.value as Alignment)} | |
value={alignment} | |
> | |
<option value="lawful good">lawful good</option> | |
<option value="lawful neutral">lawful neutral</option> | |
<option value="lawful evil">lawful evil</option> | |
<option value="neutral good">neutral good</option> | |
<option value="true neutral">true neutral</option> | |
<option value="neutral evil">neutral evil</option> | |
<option value="chaotic good">chaotic good</option> | |
<option value="chaotic neutral">chaotic neutral</option> | |
<option value="chaotic evil">chaotic evil</option> | |
</select> | |
<button | |
type="button" | |
onClick={() => | |
dispatch({ type: "alignment_shift", payload: alignment }) | |
} | |
> | |
Update Alignment | |
</button> | |
</div> | |
); | |
}; | |
function App() { | |
return ( | |
<RecoilRoot> | |
<div className="App"> | |
<ComplexDemo /> | |
</div> | |
</RecoilRoot> | |
); | |
} | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment