Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Use Reducer Components to Manage State within a ReasonReact Application

    Thomas GrecoThomas Greco

    Those familiar with redux will feel particularly at home in this lesson which shows how to use ReasonReact.reducerComponent in correlation with records and variants to manage state within a component. By the end, you'll have created a <Counter /> component that manages state internally.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson




    Instructor: In this lesson, we'll display this basic counter app using a reducer component. The first thing we're going to do is create a record for our component state.

    In here we'll just have a count of a type integer. Following this, we'll define variant called "action." We'll use this variant to define the different actions that will be used to trigger updates within our component.

    In our case we used to have increment and decrement which will be used to update the account inside of our state. These are known as "variant constructors" or "tags." One thing to keep in mind is that the name of our tags must be capitalized, or else we're going to get a syntax error.

    Before we declare our reducer component, we need to have state and action defined. Since we do, we can go ahead and create this by just saying let component, and this would be equal to ReasonReact reducer component. We're just giving this the name of "counter."

    Following this, we can then declare the make function that's going to render our component. So make takes a inaudible you prop as well as any additional props, but we can just put an underscore here as we won't be using it. Before we define any methods, we'll spread out the component that we created on line 7.

    Below component, we'll use initial state. This is a ReasonReacts form of get initial state. Initial state takes a unit and returns the state type. We can just set the default account like so. Now when, our component's rendered, account will have a default value of zero.

    Following initial state, we'll then specify our reducer method. This method is going to take two parameters -- action state, and it's going to use a switch statement which would check every case of our action variant, and update the state if it's a match.

    Inside of our switch statement we'll define the functionality for each tag inside of our actions variant, which as we know, are increment and decrement. Here, we're saying that when our increment action goes off, add one to the state count. But since we're inside of ReasonReact app, we'll need to use the ReasonReact update variant to trigger any updates within our state.

    Now that our return states wrapped in this variant, we can go ahead and add the functionality for that decrement case. This is going to be pretty much the same thing. The only difference being that increment's going to add one, and decrement will decrease it by one.

    Now that our reducer functionality is all set up, we're ready to define our render method. Render's going to take self as an argument. We can actually destructure our state off of this as well as send which will be used to trigger updates within our component. Inside this render method, I'm first just going to define a variable called "message." I'm going to say "current count."

    Then just use the string concatenation operator. Since count is an integer, we'll need to use the string of integer function, and then just pass in state.count. Following this, just going to create a div.

    First, I'll create a second-level header which is where we're going to display the message we just created, so use this. We'll use the string, the element method. Since we'll use it several times, I'm just going to pull it up top.

    Now inside parentheses, we can use that string variable and just pass message into it. Below our message header, we're going to have a button for each of our actions.

    To do this, we use onclick handlers. Like with ReactJS onclick is going to take an event. Since we won't be using it however, we'll just use an underscore to ignore it, and then we're just returning the send method we destructed above, and using it to dispatch the increment action first.

    I'm going to render a plus sign inside this button. Following this, we copy this button and paste it below, and modify the action, so it sends decrement. We'll also change this plus to a minus. When I hit "save," this file gets formatted for me. Here we go.

    If we visit our page and we refresh we see that our counter is in fact working and it's adding and decrementing as we click these plus and minus signs. Additionally, it's not running on any server but rather directly from the index, that HTML file within our source directory.

    Before we finish up, let's take a look at two more advantages of using Reason ML as well as the inaudible script compiler. If we try and use the spread syntax when updating our state, we're quickly going to be informed that the with clause is redundant since we've taken care of all fields within our state record.

    If a situation arises where we don't account for something defined within our action variant, we're automatically going to be informed of this. Here I just added increment by five which as we know, our reducer doesn't take new account, and as you can see, VS code's telling me that there's a value that's not pattern-matched -- increment by five.

    If we look at inaudible script compiler, we see that we forgot to handle possible value here, and it informs us which value we forgot to handle. Even further it tells you where exactly in your code base this value should be found, so if we weren't already aware that it was within our switch statement, we would just be able to look and be informed right away.