til / ReScript: Using useReducer in rescript-react
React’s useReducer
is great when the states get more complex than a simple value. rescript-react useReducer
is even better with ReScript’s variants.
Let’s update the code from our useState
implementation step by step to use useReducer
.
type state = DisplayValue | HideValue
type action = Toggle
These types define the state and actions of our reducer. Since we only want to toggle a value, we’ll use a variant for the state with two possible values, DisplayValue
or HideValue
. We then define the actions we can dispatch to update the state. In this case, we only need one action to Toggle
the state
.
let (state, dispatch) = React.useReducer((state, action) => {
switch action {
| Toggle =>
switch state {
| DisplayValue => HideValue
| HideValue => DisplayValue
}
}
}, HideValue)
We replace the useState
hook with this useReducer
hook. The reducer uses pattern matching on the action and toggles the state depending on the current state.
The types of state
and dispatch
are inferred from the usage as our state
type and action => unit
respectively.
<div>
{switch state {
| DisplayValue => React.string("The best value")
| HideValue => React.null
}}
<Button onClick={_ => dispatch(Toggle)}> {React.string("Toggle value")} </Button>
</div>
The updated view part uses another pattern match on the state
to either display the value or display nothing. The onClick
function now uses dispatch
to pass the Toggle
action to the reducer.
The complete code would look like this
// App.res
type state = DisplayValue | HideValue
type action = Toggle
@react.component
let make = () => {
let (state, dispatch) = React.useReducer((state, action) => {
switch action {
| Toggle =>
switch state {
| DisplayValue => HideValue
| HideValue => DisplayValue
}
}
}, HideValue)
<div>
{switch state {
| DisplayValue => React.string("The best value")
| HideValue => React.null
}}
<Button onClick={_ => dispatch(Toggle)}> {React.string("Toggle value")} </Button>
</div>
}
This is a simple example that achieves the same thing as our useState
component did but in a more complex manner. However, if we wanted to add a dedicated Display
or Hide
action the compiler would be able to help us so that we don’t miss handling any cases in our implementation.