Join Samer Buna for an in-depth discussion in this video Remounting a component to reset it, part of React Native Essential Training.
- [Instructor] Let's do one last feature for this game. Let's create a Play Again button, once the game is won or lost. We'll start with the mark-up for that button. Let's place it in this area under the numbers. We can use the button component from 'react-native'. Here is the documentation for the button component. We give an onPress event and a title for that button. Let's do that. We'll place it right here under the View Button, with a title of Play Again and we'll figure out the onPress next.
Let's see how that looks. We can see how actually the onPress is a required property. So let's provide an empty onPress function. Here's the button, looks decent. So what should this button do? This button should completely reset the game. Which means it has to reset the State of the game, but also it means that we have to generate a new target number. We have to generate a new set of random numbers and we also have to reset any timers that we did in the game.
So a simple reset for this State is not going to do. We could think about moving all the initialization of the game into it's own function and then calling this function once we want to reset the game. But that's not going to be enough because we have to clear any interval timers that we have. We also have to refire this code that initializes a new interval for the new game. So it is a bit of complicated logic here. If we start thinking about creating the reset right here on the game level, we'll have to reset the State.
We'll have to reinitialize everything that we did before the game mounts and we also have to refire the timers. So instead of going down that path there is an easier way and the easier way is just to unmount the game component and remount it. If we do that then everything is going to fire normally, the State is going to be reinitialized, the generations of all the randomNumbers is going to be fired again and the timers are going to reset normally as well.
So how do we do that? It's really simple, we'll make the App component unmount this game component and remount it. And there is a simple trick to do that in React. If we pass this game component a key property, any key property, React is going to identify that particular game with that key property. If we later change that key property, React is going to think that this is a brand new game and it will actually unmount the previous game and mount a new one.
So all we need to do is have some kind of gameId here and just change that gameId every time we want a new game and the easiest way to do that is to place this gameId on the State of the App component. So we can do something like, this.state.gameId. And we'll initialize this gameId right here on the State of the App component. So state = an object and that object have a gameId, we can start the gameId with one. Now to reset to the game all we need to do is change this gameId into something else.
So let's write a resetGame function in here. No arguments for this function. And it will simply set the State. It will change the gameId to be the prevState.gameId + 1. Very simple, so if we call this resetGame function, React is going to unmount the previous gameId with one and remount a new one with two. So now we need to pass this reset game function reference to the game component so that it can call it when we hit Play Again.
So from the perspective of the game component we can name this feature... onPlayAgain. This will be the App component... resetGame function. Let me format that a little bit and here we go. The game has a key, you can increment that key from the App component. The game also has a behavior that it can invoke to reset the game and we named it onPlayAgain. So we'll go to the game component and inside the game component we'll define this onPlayAgain function which is a...
PropTypes function and it's also required. Now the reset button the onPress here can just be this.props.onPlayAgain... just like that. And this should actually work, let's actually test it real quick. So got a game, the timer is decrementing and we can Play Again. Did you see that? Everything reset right away, because React has a new game.
A game with a different ID than the previous one. So even if the game is lost like that, Play Again will just reset it. So this is great but we want to show the Play Again only when the game is lost not when the status is still playing so we can do that simply with a conditional here. So we'll put the whole Play Again button in a conditional and we can do something like this.gameStatus... is not playing...
show this Play Again button, format this. Here's the condition, if the game status is not playing, we'll go ahead and show this Play button. Let's test that. The game starts and there is no Play Again button. Now once the game hit conditional where it's won or lost, the Play Again button is going to show up and we can play the game again. Testing the won condition, same thing. If the game is won, we can Play Again.
So I think this is a good set of features to call this game done and move on to a different example. However before we do that, I'd like you to think about more features to add to this game. Maybe you can focus on two features. The first feature is when you Play Again, make the game harder and you can do that by controlling the parameters that we send to the game, the randomNumberCount, the initialSeconds all of these are controllable as well. So that's one feature, make the game harder as it progress.
The other feature, keep a score. Whenever the game is won, give the player some kind of score and that score persists between games. So the more games the user win, the higher the score. So you want to think about where to place this score and how to control it. I hope you like this example. Let me know if you have any questions about what we did or about the challenges. In the next chapter we'll build a different example and this time we'll work with data and actually remote data so that we know how to do things asynchronously.
- Hello React Native on iOS and Android
- Styling React Native components
- Platform APIs
- Building a simple game app and a data-driven app
- Using the Fetch API
- Creating an animation loop
- Testing on Android
- Changing an app logo and a splash screen
- Using TestFlight with internal testers