Get Started with React TypeScript by building Tic Tac Toe (with Hooks, TypeScript, CSSinJS)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] in this tutorial on react we will be creating a tic-tac-toe application using the typescript template and we will be using react hooks for our state management and css and js for styling our application so let's go getting started with a react application is extremely easy nowadays because all you need is a simple node installation and once you have node installed you get access to this command called npx which you can use to execute the create react app package passing in the name of the project that you want to create which in our case will be tic tac toe and passing in an optional template for which we will be passing in typescript this will create the project folder and install any dependencies that this project will need so once this installation is complete all that we need to do is to cd into that directory and start playing around with the code [Music] now all the application source code is located in the source folder if you want to play around with the application open up the terminal and type in npm start this will start the basic react application and it will actually launch a browser instance at the url as well which you can see on the side over here it actually tells you that if you want to modify what is being displayed on screen right now go into the source app.tsx and make any modifications for example if we change the text to learning react you can see that the ui application refreshes with the new text [Music] now for the purposes of building our tic-tac-toe application we will go ahead and delete the main app component that currently exists so we will delete app.dsx app.css and app.test.tsx now let's go ahead and create a first react component in the form of game.tsx located in the components folder this component will be the main application entry point for our tic-tac-toe game now the first thing that we need to do in any dsx file is to import the react module now creating react components is extremely easy all that they are are simple functions that return some jsx jsx can be thought of as html embedded within javascript now the great thing about embedding html within javascript is that you get all the programmatic control to modify the html structure that you intend to return from any given component next we go ahead and export this function from our javascript module so that we can render this into the dom within our main application entry point index.tsx now currently it's pointing to app but we will go ahead and import the game component from component slash game and then render it into the main application using once more jsx now since we have npm start running in the background we can actually see our game component rendered into the ui if we go ahead and open up the browser and you can see the hello world displayed within the ui now react is great for rendering jsx aka html to the ui however it doesn't have a great css management solution built in however the community has stepped up in this area and there are plenty of css and js solutions for this particular case we will use styled components which is by far the most popular solution nowadays now to install style components we install the style components module and then we also install the type definitions for style components so that we can use it easily within typescript now once the installation is complete we jump back to our ide and bring in the default export called styled from style components now we will be using this import to create components that are styled using css now if you have a think about the ui that we're trying to build or really any user interface that you can imagine it can be thought of as a combination of rows and columns for example at the root of the application we have a row of two items on the left we have the status and the main game board and on the right we have a history of all the moves that have taken place in this game and then the first row can be further broken down into a column of two items first with the status and then with the main game board and now when you think about the game board itself it is also a combination of rows and columns it is a column consisting of three rows and each row contains three squares now one more thing to note about this row and the column component is the ability to create gap between the items in the row or column now creating this row and column component is extremely easy with css flexbox now both the row and the column component will take the cap as a layout property so we will create a common type to be shared by both of them first up we will create the row component now the easiest way to create a component using styled components is to use styled.tag name for the row and the column we will be using divs so for row we go ahead and use style.div passing in the type of the props that are going to be expected by the generated component and then provide a list of css key value pairs here we are using css flexbox so we set display to flex and for the row component we set the flex direction to row and for the gap we will use the past in props and look up the gap to generate the gap value now to ensure that our row component works as expected we will create a row with three items with a gap of 20 pixels between each item now if we jump to the browser you can see that it works as expected now the column component will be the same as the row component the only difference will be that the flex direction will be column and now if you place a number of items within a column you can see that we get a nice vertical layout with the gap that was specified now we will create different components for different portions of the ui first up we will create the boat component which will be our main game board next we will create a separate component for the log of all the steps that will be taking place in a given game and then we will use these two components from within our main game placing them in a row so that they are right next to each other in a nice horizontal layout and then we will place the game board within a column along with the status to give us a vertical layout from status to the game board and now if we jump to the browser you can see that we have a row of the status and the board on the left and the game log on the right and then the status of the board are in a nice column layout now within the game board we will need a component that will represent each square that the user can interact with we will be styling this using styled components and our base component will be a button for the styles of the component we will give it a fixed height and a width clear the background to make it a nice white give a border to create the separation between the different squares clear the padding and provide a default font size and make the font weight bold next we use this style square component as the root of our square component and we will put a placeholder for the x within our square component for now and as we discussed before our game board is simply a column of three items where each item is a row consisting of three squares now if we jump to the browser you can see that we get a nice game board with all the squares currently filled with x now a great thing about using a button as the base of a square is that we get nice focus states and outlines as the user is going to interact with the ui application this is great for accessibility and whenever possible if you have an interactive element it is nice to use a button now a great thing about react hooks is that they allow us to separate the game logic from the game rendering now that we have the rendering down we will create a new file called game state that will contain all the logic and the brains of the main tic-tac-toe game without having to worry about how this game is going to be rendered to the screen now all code can be thought of as data and logic that manipulates the data without typescript we will only be able to document the logic that manipulates the data and we would have to keep the data structures within our own mind but because of typescript we can write down the data structures in typescript so that we don't have to keep them in our mind and they can be enforced by the compiler and they can be handed over to the next developer with ease at the base level we have the value of any given square within the game board we can represent that as a union of an x or an o or when it is empty represented as null and our complete both state in any given point in time is simply an array of these values now because our board will only ever contain nine values for the nine squares of a standard tic-tac-toe board we will create a utility to initialize an array of length 9 all with null values speaking of utility methods we will create a function to calculate the winner from any given both state now in order to win at tic-tac-toe you need to have the same value in any of the three rows or any of the three columns or any of the two diagonals giving us a total of eight possible winning combinations so to see if someone is a winner in any given both state we look through the winning combinations pick up the squares from the winning combinations and ensure that the both state has a value for the first square and that the value on the first square is the same as the value of the other squares that would be in this winning combination if so we simply return the value from the first square which would be the winner otherwise after the loop we return now now in terms of the overall game state we will maintain a history of all the different both states between different moves and a step that we are in within the current history array now let's go ahead and create a first react hook all our game state will be maintained by this hook and the rules for hooks is that every hook function must start with the word lowercase use fundamentally any hooks that you create eventually boil down to calling sum hook function again starting with use from within the core react library since we are maintaining the game state we will use the use state hook that we will import from react now the usted hook takes a generic argument to specify the data structure for the state that will be managed by this hook it takes an initial state again conforming to the game state data structure and then returns an array of two items the first item is the current game state and the second item is a method to go ahead and modify this game state to a new value now from the use game state function we will return the current game state that is being maintained by the u state hook however we will not expose the set gamestate method to our consumers and instead we will create nice utility methods to modify the game state in a safe fashion now before we do that one more thing to think about is nice computed states now from the current game state the current port state is simply the lookup by the step number from the history now we could expect our consumers to do this themselves however it is nice to calculate this value up front and return it from a hook so that they don't have to do this work now another nice thing that we can pre-compute is if x is the next person that needs to make the move for any even step numbers as well as the zeroth step x will be the person that needs to make the move so we calculate that and return that up front another thing that we can pre-compute is if within the current game board we already have a winner so we use the calculate winner utility method that we saw previously pass in the current game board and store the result in winner and return that from our hook now let's create those utility methods that can modify the game state first up we have the user interacting with a particular square by clicking it within this method we load up the history up till the current game step point and load up the both state by looking up the last point in that history and if there is already a winner or the square within the current post state is already occupied by some value then we do nothing and simply return otherwise we create the new birth state by creating a copy of the current port state and then within this new board state we use our same old person2 function to populate the square with the person whose move it is supposed to be finally we push this new board state into the history and then use the setgamestate function to set up the history and the step within the history now the other utility method that we need for modifying the game state is the ability to jump within any point within the history so we create this function jump 2 that takes a step number and simply uses set game state to preserve the history but change the step number within game state next we simply return these two handle click and jump to methods from within our main use game state hook and that's it we don't need any additional logic as far as maintaining and accessing the game state for tic-tac-toe is concerned now as far as using this use game straight hook is concerned we jump to our main game component and simply invoke the use game state function and then destructure its return value to get access to the things that it provides now let's start wiring up our ui to this state the computed state and the mutating methods first up we will replace the placeholder status text by looking up whether we have a winner and if we have a winner we will indicate the winner otherwise we will indicate the next player that is to move by using x is next next we will wire up the current game board now the board really cares about what the current game state is which we will pass as current and then whenever the user clicks a particular square we want to wire that to the handle click function provided by our use game state hook now at this point our boat component doesn't actually take these properties which is why we are seeing red squigglies in our ide under the board prop now in order to make this component accept these properties first up we will define what these properties are going to look like so we create a new typescript type called boardprops with a member board of typeboard state and a member on click which will be a function that needs to be invoked with a given square number now in order for the board component to accept these properties we simply add them to the function argument for board now the next step would be to wire this board state and the on click to the individual squares within our board now if you think about the square component the two properties it needs are the current value that it needs to render as well as a method that it needs to invoked when the user clicks a particular square now once more in order to make the square component accept these properties we simply add the props argument to the square function and then within the function body we wire up the on click to the style square and instead of a placeholder x we use the past in props dot value to render the square value and now because a square component requires these properties to be passed in any instance where these properties are not passed in for example within our board component is now highlighted by red squiggly now if you wanted you could pass in the value by looking up from the index using the board and then on click triggering the on click with the same index but this duplication of index number can be a bit problematic so instead we will create a utility method to create the properties for a given square with a given index this will ensure consistency in the value that we look up by the index from the board and the on click that we trigger with the same index if that particular square gets clicked and now instead of passing the individual properties to the square we will invoke this create props function and spread the value and the on click that it returns into the properties for a given square and then we can simply repeat this process with different index number for the different squares within our game board and that's it for the game board the final component that we need to wire up is a log component which will give us a history of all the steps that have taken place along with the ability to jump to a particular point within that history now of course at this point this component doesn't accept these properties so we can jump to the component by command clicking into the function and then for this log function we will create log props with a history of type both state array and a jump to function that takes a step number to jump to a particular point in the history and once more in order to make this function accept these properties we simply add the function argument and now we can replace our placeholder with a simple map over the history array now whenever we render an array within react it requires a key property to ensure that it can re-render it without having to create and destroy dom nodes again and again so we wire up the key for the list item to the index and then we have a button that you can click to trigger a jump to that given index and then within that button we simply render go to if the index is 0 start otherwise go to move number index and that's the end of our application code we can jump into the browser and start playing detector with our self now as you click the different squares within the game broad the status updates to indicate the next player that is going to move the history continues to increment till we have a winner and now at this point you can jump to any point within the history to see what the board looked like at that point and even start clicking on the board again to start a new history chain from that point now feel free to play around with this game and your code as much as you want this complete game will also be available on github so you can clone the final game state and start playing around with that now one more thing that i want to talk about is code organization we intentionally kept all the components within game.tsx to keep our code simple while we were writing it now whenever you find components that can work in isolation it's a nice idea to move them into their own module file you can select a list of types and functions within vs code and typescript will provide you a nice refactoring to move these into their own file so we can move the log props and the log component into its own log.tsx module and then we can repeat the process for our square component and we can even do the same process for our board component and finally from the top of our file we will move the two layout components into the layout.tsx module so now we have this nice game component that uses the game state and then renders out the board and the log components that's it for this lesson on building tic-tac-toe with react and typescript and hooks using css and js smash that like and subscribe for more content like this and i will see you in the next one
Info
Channel: Basarat Codes
Views: 2,504
Rating: undefined out of 5
Keywords: typescript, javascript, basarat, that typescript guy, typescript deep dive, react, node, npm, angular, tic tac toe, react hooks, css in js, styled-components
Id: YElDQgy8GMY
Channel Id: undefined
Length: 20min 30sec (1230 seconds)
Published: Sun Aug 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.