Last active
November 29, 2020 08:52
-
-
Save jsiebern/ac9a3ce507ad047f7c1d594446cd7b4e to your computer and use it in GitHub Desktop.
This file contains 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
module Store = { | |
type action = | |
| Increase | |
| Decrease | |
| SetUsername(string); | |
type state = { | |
count: int, | |
username: string, | |
}; | |
type storeBag = { | |
state, | |
dispatch: action => unit, | |
}; | |
let reducer = (state: state, action: action) => | |
switch (action) { | |
| Increase => {...state, count: state.count + 1} | |
| Decrease => {...state, count: state.count - 1} | |
| SetUsername(username) => {...state, username} | |
}; | |
[@react.component] | |
let make = (~children: storeBag => React.element) => { | |
let (state, dispatch) = | |
React.useReducer(reducer, {count: 0, username: ""}); | |
children({state, dispatch}); | |
}; | |
}; | |
module Login = { | |
[@react.component] | |
let make = (~store: Store.storeBag) => { | |
let (username, setUsername) = React.useState(() => ""); | |
<div> | |
<input | |
type_="text" | |
value=username | |
onChange={e => setUsername(e->ReactEvent.Form.target##value)} | |
/> | |
<br /> | |
<button | |
onClick={_ => { | |
store.dispatch(SetUsername(username)); | |
ReasonReactRouter.push("#loggedin"); | |
}}> | |
"Login"->React.string | |
</button> | |
</div>; | |
}; | |
}; | |
module Screen = { | |
[@react.component] | |
let make = (~store: Store.storeBag) => { | |
<div> | |
<b> {("User: " ++ store.state.username)->React.string} </b> | |
<br /> | |
<br /> | |
<span> | |
{("Count: " ++ string_of_int(store.state.count))->React.string} | |
</span> | |
<br /> | |
<button onClick={_event => store.dispatch(Increase)}> | |
"Increase"->React.string | |
</button> | |
<button onClick={_event => store.dispatch(Decrease)}> | |
"Decrease"->React.string | |
</button> | |
</div>; | |
}; | |
}; | |
module Router = { | |
type route = | |
| Login | |
| Screen; | |
type action = | |
| SwitchRoute(route); | |
type routerState = {activeRoute: route}; | |
let reducer = (state: routerState, action: action) => | |
switch (action) { | |
| SwitchRoute(route) => {activeRoute: route} | |
}; | |
[@react.component] | |
let make = () => { | |
let (state, dispatch) = React.useReducer(reducer, {activeRoute: Login}); | |
let url = ReasonReactRouter.useUrl(); | |
React.useEffect1( | |
() => { | |
switch (url.hash) { | |
| "loggedin" => dispatch(SwitchRoute(Screen)) | |
| _ => | |
Js.log("Could not find route"); | |
Js.log(url); | |
}; | |
None; | |
}, | |
[|url|], | |
); | |
<Store> | |
...{store => | |
<div> | |
{switch (state.activeRoute) { | |
| Screen => <Screen store /> | |
| Login => <Login store /> | |
}} | |
</div> | |
} | |
</Store>; | |
}; | |
}; | |
[@react.component] | |
let default = () => <Router />; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment