The library implements the "model-update" part of the "model-view-update" elm architecture, leveraging React as the "view" part and implementing the missing part of state and effect management.
🚧 Not production ready (yet), but trying out is highly encouraged 🚧
Can be installed via:
npm install --save "https://github.com/MargaretKrutikova/reason-react-elmish"
and added to bsconfig.json:
"bs-dependencies": [
"reason-react-elmish"
]
Peer dependencies are react
, reason-react
and bs-platform
.
First, define your types for message and model, implement the update function and effectful functions (if any).
// AppModel.re
type message =
| FetchUsersRequest
| FetchUsersSuccess(userApiResponse)
| FetchUsersError;
type data =
| NotAsked
| Loading
| Error
| Success(userApiResponse);
type model = {data};
let fetchUsers = dispatch => {
Js.Promise.(
Caller.fetchUsers()
|> then_(response => dispatch(FetchUsersSuccess(response)) |> resolve)
|> catch(_ => dispatch(FetchUsersError) |> resolve)
)
|> ignore;
None;
};
let update = (_, message) => {
switch (message) {
| FetchUsersRequest => ({data: Loading}, Some(fetchUsers))
| FetchUsersSuccess(data) => ({data: Success(data)}, None)
| FetchUsersError => ({data: Error}, None)
};
};
let initModel = ({data: NotAsked}, None);
0: <UNKNOWN SYNTAX ERROR>
Setup your elmish store with all of the above and your initial model with initial effect (if any).
// AppStore.re
include Elmish.Make({
type model = AppModel.model;
type message = AppModel.message;
let update = AppModel.update;
let storeEnhancer = None;
let initialModel = AppModel.initModel;
});
0: <UNKNOWN SYNTAX ERROR>
See example file ./examples/AppModel.re
and ./examples/AppStore.re
.
Then hook in your store into the react component tree somewhere at the root:
// Index.re
ReactDOMRe.renderToElementWithId(
<AppStore.ElmishProvider> <Root /> </AppStore.ElmishProvider>,
"root",
);
0: <UNKNOWN SYNTAX ERROR>
and use the hooks to get access to the model and dispatch in your components:
let selector = (model: AppModel.model) => model.data;
[@react.component]
let make = () => {
let dispatch = AppStore.useDispatch();
let result = AppStore.useSelector(selector);
<div>
<button onClick={_event => dispatch(FetchUsersRequest)}>
{React.string("Fetch users")}
</button>
</div>;
};
let selector (model : AppModel.model) = model.data
let make () =
let dispatch = AppStore.useDispatch () in
let result = AppStore.useSelector selector in
((div
~children:[((button
~onClick:(fun _event -> dispatch FetchUsersRequest)
~children:[React.string "Fetch users"] ())[@JSX ])] ())
[@JSX ])[@@react.component ]
npm install
npm start
# in another tab
npm run watch:bs