Implementing JavaScript functions in a UI

At this point, you've seen how to get input from the user controls on your UI, work them through the Redux life cycle, and have the end product show back up in the UI as new props. In this section, we're going to dig into the functions in our UI that tie into the user controls.

When our reducer receives the action from the dispatch function, it creates and sends this object to the Redux store, and it does so along with all the other reducers our application may have, so we have a rootReducer constant that combines all of these reducers. The following screenshot shows what this looks like:

Here you can see that we've defined a new key named game in rootReducer, and it's going to get populated with the data from gameReducer. This is what gets sent to the Redux store, and we know that the Redux store is going to send this into our component as props. So, in our JavaScript file for our game UI, we have this function mapStateToProps(), as you can guess from the name, this is what maps the Redux state to the props in the component.

So, all the values that we sent to the Redux store can be accessed and read in our component as follows:

this.props.game.wager
this.props.game.playerNumber
this.props.game.mysteryNumber

All props are read-only and you can't change them. We'll look at how to change them in just a minute, but what about when they change on the backend? How does our UI update if the value of one of these keys changes in the Redux store?

Well, depending on whether you're using React 15 or React 16, there are two methods you can use, both behave similarly, but as you can tell from the name, they fire at different times. In React 16, we use componentDidUpdate() , and it receives a parameter called prevProps that allows us to compare the value of the props with their previous value and then take action accordingly. In React 15, we'll use componentWillReceiveProps(), which fires before the component receives the new properties. The parameter name reflects that as well. It's a parameter called nextProps, which contains what the new incoming values for the props are. You can use componentWillReceiveProps() in React 16, so if you're upgrading an existing React 15 app to React 16, this will still work.

In the next version of React, componentWillReceiveProps() is going to be marked as deprecated and then be removed in the version after that. When we add these functions to our component, we need to evaluate why it was called. It's going to get called a lot and by things that you don't care about, so you need to evaluate the conditions to see if you care about it or not. Let's look at the following example:

We'll start with an if statement that checks to see whether game.transactionHash from the nextProps parameter is different than the one in this.props. If it is that tells us we have a new transaction hash, and since a transaction hash is specific to a transaction, we know that the player has completed a round of the game. Next, we set our success key; remember, this was the key that we set to true if the promise wrapping our contract transaction completed successfully, and we set to false, if the promise was rejected. This gives us an opportunity to relay an error message if we need to. If our promise resolved successfully then we'll have some new transaction details to add to our game history window. I'm storing that game history as an array in the component state.

So, let's create a new variable for our history, and then we'll push all of the details of our latest transaction onto that array. We can't update the component state directly, so we call this.setState and set the history value to the new history array we just created. And finally we've got a snackbar control, which is a little toaster-style pop-up control, and the values for it are stored in the component state as well, so we can update them and assign values to them.

When this renders, it's going to translate into a sentence that reads something like lost ten ether, or whatever the correct values are, and add the results from that round to the history window as seen in the following screenshot:

Other than updating the state variable, we didn't have to do anything to get our UI components to handle the update on the page, because we bound the control to the state variables. React knows to re-render them when they change. Because React only wants to render variables that change, it's important to have this key when we map our history array. The key allows React to identify each item in the array uniquely, and only render the ones that have changed. And now, it's time for our last section today, the assignment.