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.

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

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

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

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

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

  1. Set up a new React project using Vite
  2. Show a list of pokemon names
  3. Wrap the list in a page structure (containing a nav bar with dummy links)
  4. Stretch Goal: Test your components using Vitest and React Testing Library
Exercise goal

Hints

  • Setting up a new React app:
                    
                        $ npm create vite@latest pokedex-vite
                          > React
                          > Typescript + SWC
                        $ cd ./pokedex-vite
                        $ npm install
                        $ npm run dev
                    
                
  • Start building in App.tsx
  • Create a (hard-coded) array of Pokémon and render it as a list
  • Create components for the list entry, list, and layout
  • Extract components into separate files before a file gets too big

Solution

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Solution continued

                    
                        
                    
                

Solution continued

PokeListEntry.test.tsx
                    
                        
                    
                

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?