MUNI inQool as 5. React - basics What is React? 1 React component tree 2 Function and Class components 2 Props 3 PropsWithChildren 4 Rerendering 5 State 5 State in Class components 5 State in Function component 6 Tic-Tac-Toe in React 7 Grid system 8 Basics 9 Breakpoints 10 Implementation 11 Custom styles in Material UI 12 makeStyles and useStyles 12 Implementation 13 Implementing logic 14 Mouse events 16 Implementation 17 Material Ul icons 19 What is React? React is a declarative, efficient and flexible JavaScript library for building user interfaces. Components allow you to split the Ul into independent, reusable pieces, and to think about each piece in isolation. 1 MUNI £9 inQool React component tree React components are structured into a hierarchical tree structure. The structure ensures a one-way data flow (via props). The children cannot update the data it receives from its parent. If data needs to be updated, children can receive another prop from the parent, that contains a function to update it. Each component is declaring what will be rendered on the screen based on the props it renders. Function and Class components There are two basic ways to define a React component. In the previous lesson it was created by CRA component App. This type of component is called a Function Component. const App: React.FC =()=>{ return
Hello worlck/div>j } You can also write this component via ES6 Class (syntax was mentioned in lesson 2). Class components have a set of methods, each of them evoked in concrete time during the 2 MUNI £9 inQool component's life cycle. In the following example, the App component has only a single lifecycle method render which serves the same purpose as the return value of a function component. In other words, it renders JSX on the screen. class App extends React.Component { render() { return
; } } Since we will be using the newer function components and hooks we won't go deep into the class component's lifecycle and other related topics. While React developers said that there are no plans of deprecating class components, we can safely assume that they won't be receiving any new features. Props React components accept arbitrary values (called "props" which is short for properties) and return React elements describing what should appear on the screen. We can expand the example of the function component above with props like this. type Props = { name: string }j const App: React.FC = props => { return
Hello {props.name}
j For example Typography component from MaterialUI in the following snippet uses a variant prop. •typography variant="h5">Sign in It's common to use destructuring on props, so many examples you come across will look like this. 3 MUNI £9 inQool as const App: React.FC = ({ name }) => { return
Hello {name}
j PropsWithChildren When you inspect the type of props you get when using TypeScript, you can see that your Props type is wrapped in a PropsWithChildren helper which adds the children: React. ReactNode to your props. The children prop is a special prop that each component has and it's value is equal to what you pass to it between it's opening and closing tags. type Props = { title: string }j const Button: React.FC = ({ title, children }) => { return j }J // Usage Here you can see one simple example where a button component simply passes the children prop to the DOM element it renders. You can also change the type of children prop (which TypeScript will also remind you of) to anything else. Most commonly it's used to expect an array of components or in a pattern called Render props. You can find this pattern used in various component libraries and it may look something like this. // Type of children is (close: () => void) => ReactNode instead of ReactNode {close => (

Hello

)} 4 MUNI £9 inQool as
Rerendering Important note about props is that the component is rerendered each time the props change. In class components, you could use multiple methods to change this behaviour, but in function components there was no such a thing until Hooks came along. Hooks are what allows functional components with linear code execution to have things like persistent state and other features, but more on Hooks later. State Each component (class or function) is able to store local state. Below we will go over differences in these two approaches. State in Class components type Props = {}; type State = { foo: string }j class App extends React.Component { constructor(props: Props) { super(props)j this.state = { foo: 'bar'j } renderQ { return
{this.state.foo}
j } } State and props are key mechanisms in React and both invoke rerendering the component after the change of it's values. It means that if we have a button element calling setstate method (reserved method in Class component, which sets values into state) we can change the value of 5 MUNI £9 inQool this . state . f 00 like this... ... and then the state will contain the value of "baz" under the foo key and the component will also be rerendered. State in Function component import Reactj { FCj useState } from 'react'j const App: FC = () => { const [foOj setFoo] = useState('bar')j return
{foo}
j In function components there is no constructor nor reserved setState method. We need to use the already mentioned Hooks, specifically useState hook. This hook returns a tuple consisting of current value (foo) and setter (setFoo) and takes an optional value which if provided will be the initial value of this state. Note: Array destructuring is used to extract the value and setter from the returned value, therefore you can choose any names for these two variables. You should still follow the convention [x, setx] whenever possible though. Note: If an initial value is provided, the type of the return value is inferred from it. However if there is no initial value you should explicitly provide the type. Also in this case the type will automatically be expanded with undefined. const [foOj setFoo] = useState(); // Type of foo is string | undefined There may be cases (we will even come across one in this week's task) where you want to change state based on its current value. Most commonly this is used for boolean state which you simply want to toggle between true and false. For this use case, the set function instead of value can accept a function that provides you with the real and up to date value of its state (this is usually most important when using state setter in asynchronous code). 6 MUNI £9 inQool as const [flag., setFlag] = useState(false); const toggleFlag = () => setFlag(prev => Iprev); Tic-Tac-Toe in React Now let's demonstrate all the basics on a Tic-Tac-Toe game example. Our starting point will be a clean Create React App project. yarn create react-app tic-tac-toe --template typescript First create a new components folder and do some minor cleanup of CRA template. This project will contain multiple components declared in multiple files so it's useful to organise your files a bit. We can now prepare basic components of the game. Create two new files, Square . tsx and Board. tsx in the components folder. Square component will represent one field in the tic tac toe board. import Reactj { FC } from "react"; const Square: FC = ({ children }) => (
{children}
)J export default Square; Board component will represent the board of the tic tac toe game, containing Squares. import Reactj { FC } from "react"; import Square from "./Square"; const Board: FC = () => ( l 7 MUNI £9 inQool as export default Boardj Now we need to import the Board component in App.tsx and add it into it's JSX. At this point we created a tree of components App -> Board -> Square. We can inspect it in the Chrome React extension. rendered by Board App createLegacyRioot () react -do^JlT.e.l source ;□ Board.tsx:S Next we should prepare our components and style them. For that we will be using the MaterialUI framework. yarn add @material-ui/core @material-ui/icons @material-ui/styles Note: Since @material-ui is written in TypeScript and comes with it's own typings we don't need to instal any additional ©types packages. Grid system The grid system creates visual consistency between layouts and allows flexibility across many different screen sizes and orientations. It is more related to design of web pages and not something specific to React or Material Ul. The grid system from Material Ul we will be using follows many common principles of any grid system: Based on a 12-column grid layout Supports two types of components: containers and items 8 MUNI £9 inQool Widths of items are specified in percentages, which allows us to create a fluid and responsive layout, relative to their parent element In Material Ul, there are five grid breakpoints: xs, sm, md, Ig and xl Basics Breakpoints refer to screen widths at which the specific rule is applied (you can see the exact values and more detailed explanation in Mill's documentation'). Sizes of breakpoints are specified in a mobile first approach, therefore by specifying xs size, we also set all larger sizes. xs=12 xs=6 xs=6 xs=3 xs=3 xs=3 xs=3 9 MUNI £9 inQool Breakpoints By providing multiple values, the grid items will be sized based on current breakpoint. On screens larger than sm breakpoint (>=600px): On screens smaller than sm breakpoint (<600px): xs=12 xs=12 sm=6 xs=12 sm=6 xs-6 sm=3 xs=6 sm=3 10 MUNI %f inQool xs=12 xs=12 sm=6 xs=12 sm=6 xs=6 sm=3 xs=6 sm=3 xs=6 sm=3 xs=6 sm=3 Implementation Our tic tac toe board will consist of 3 rows and 3 columns of Card components spaced out in a Grid. We can use the fact that by default Grid wraps it's items into the next row if they don't fit into it's 12 columns. For styling we will use a Container component that will make sure our board isn't stretched on large screens and for styling the squares we can use the Card component and it's CardActionArea which take care of distinguishing between squares and also styling the click action. const Square: FC = ({ children }) => ( •typography variant="h5">{children} const Board: FC = () => ( l 2 11 MUNI £9 inQool as 3 4 5 6 7 8 9 Output on the screen should now look like this: Custom styles in Material Ul Material Ul provides a solution for custom styles based on the CSS-in-JS concept. All styles are held in js files, there is no need to keep static . ess files. It comes with many powerful features like dynamic styles, theming... We will be using this modern solution too, so let's describe how. makeStyles and useStyles The most crucial part is located in package @material-ui/styles and it is the makeStyles function. With makeStyles we can create a hook useStyles which injects styles into our app's markup during runtime. These styles can be found inside the head selection when you inspect the running app. 12 MUNI £9 inQool as T