First Components

Essential React

Simple React Component

Greeting.tsx
                    
                        
                    
                

Single-line vs. multi-line JSX

Multi-line JSX should always be wrapped in parentheses.

Use a code formatter like Prettier .
Enforce it by integrating it with ESLint

Component Splitting

Importing another component

WelcomePage.tsx
Don't build monoliths. Split your components!

Fragments

Components always return a single node .

If you want to return multiple nodes, wrap them in a Fragment to avoid rendering an unnecessary <div> .

Fragments

Using the long-form Fragment is equivalent to the shorter <>…</> syntax.

We will see in a bit in which situation the long-form <Fragment> is useful.

Exercise

  • Setup a new React project with
                      
                          $ npm create vite@latest pokedex-vite
                            > React
                            > Typescript + SWC
                          $ cd ./pokedex-vite
                          $ npm install
                          $ npm run dev
                      
                  
  • Create a PokeListEntry component to show a pokémon name like 'Bulbasaur' kept in a constant
  • Consume this component in the App.tsx

Solution

PokeListEntry.tsx
                    
                        
                    
                

Solution continued

App.tsx
                    
                        
                    
                

Props

We can pass data to child components by setting their props (properties)

A prop can have any type, e.g. it can be a JavaScript primitive, an object, or a function

Props can be defined as required or optional

Pass functions as props to listen to events emitted by child components

Define Props on a component

Exercise

  • Create Props for your PokeListEntry component expecting an optional name
  • Set a default name if property is not passed by consumer
  • Use object destruction

Solution

PokeListEntry.tsx
                    
                        
                    
                

Testing

Our components can be tested using the Vitest and React Testing Library

Add the library

Add in the package.json in the scripts section

Configure

setup.ts

Configure

vite.config.ts

Testing our dumb component

Greeting.test.tsx
npm run test

TDD - Test Driven Development

It is a good practice to conduct TDD wherever possible

Let us amend the component such that we can set the name through an name property

Add new test case

Greeting.test.tsx
                    
                      
                    
                

Implement / Make the test green

Greeting.tsx

Refactor

Refactor your code such that it is extensible and easy to understand

Cheat Sheet

  • getBy* - verify that an element/node is present at this very moment. Throws an error if element/node is not found.
  • queryBy* - similar to getBy* , but will not throw an error if the element/node is absent.
  • findBy* - verify that an element will be present, e.g. upon completion of an asynchronous API-Call

Find more about queries here

Exercise

Solution

PokeListEntry.test.tsx
                    
                        
                    
                

Solution continued

PokeListEntry.test.tsx
                    
                        
                    
                

Follow-Up: Continuous Integration

On your CI pipeline you typically want to ensure the quality of the solution

  • npm run test:ci which is defined in package.json with the command vitest run without watchmode
  • npm run lint
  • npm run build

List

To render a list of items, we call the map function on an array.
In the callback we map the array item to a JSX element.

We can map to an HTML element or to a custom component.

The JSX element returned from map must have a key prop.

This is a special prop used by React internally to distinguish the elements. It must be unique within the list (e.g. an entity ID).

Use a Fragment to return multiple elements from map .

Here we can't use the shorter <>…</> syntax. Only Fragment can take the key prop.

The children prop

Like HTML elements, React components can be nested:

            
                
            
        

The parent component receives the child components through the children prop.

            
                
            
        
            
                
            
        

The children prop can be rendered in the parent component's JSX.

Exercise

  • Create a (hard-coded) array of Pokémon
  • Render all Pokémon names in a list (hint: add a new PokeList.tsx component)
  • Make the name in PokeListEntry.tsx required
  • Write tests for the list
  • Create a Layout component which wraps the list with a page structure (containing a nav bar with dummy links)
Exercise goal

Solution

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Recap

We learned…

  • How to create a simple React component and import it
  • Use props to pass data into a component
  • Write tests to verify the components behaviour
  • Render a list of components
  • Create wrapper components using the children prop

Questions?