DEV Community

Rickard Natt och Dag
Rickard Natt och Dag

Posted on • Originally published at willcodefor.beer on

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 useStateimplementation step by step to use useReducer.

type state = DisplayValue | HideValue

type action = Toggle
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

We replace the useState hook with this useReducer hook. The reducer uses pattern matchingon 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>
Enter fullscreen mode Exit fullscreen mode

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

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>
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)