React Events, State, and Style

Web Development 2 WEBD-2008

Red River College

Introduction

Newtons-cradle-256213_640

In the Introduction to React module you learned that a React component is a function that returns JSX markup. You also learned that you can customize your components by passing in “props”.

Beyond this customization you were creating static markup that remains unchanged once rendered.

In this module we introduce the dynamic aspects of a React that allow components to persist state and to react to user events.

Objective

By the end of this module, you should be able to:

Module Plan

Reacting to Events

Adding events to JSX element is done using camelCase element attributes.

In this example we are adding an “on click” event to a button with the onClick attribute:

See the Pen Events in React by Kyle Geske (@stungeye) on CodePen.

📢 Note:

  • The function we are binding to is nested within our component. Functions defined within functions are a thing.
  • The event attribute value is the name of the function inside curly braces.

Resources

Inline Event Handlers

Short event handlers can be written inline within the attribute value:

See the Pen Inline Events in React by Kyle Geske (@stungeye) on CodePen.

The Event Object

The event object can be received as a function parameter and used to prevent default actions or to access the target DOM node:

See the Pen Event Parameter React by Kyle Geske (@stungeye) on CodePen.

👆 event.preventDefault() stops browser from following the link.

event.target.href retrieves the href attribute of the target <a> DOM node.

The State of Things

React components can be configured in two complimentary ways:

  1. We’ve seen that properties can be passed to components as JSX attributes. These props are supplied by a component’s parent. When these props change the component is re-rendered based on the new data.

  2. Components can also manage their own internal “state” by way of special getters and setters. When a setter is used to change a component’s state the component is re-rendered.

You can think of a component’s state as being similar to an object’s state. Like with an object’s instance variables, every maintains its own unique state.

The useState Hook

React has a concept called “Hooks” which are functions that let you “hook into” a component’s state and its lifecycle.

Normally, variables in Javascript functions go out of scope when a function exits, but the useState hook allows us to preserve the internal state of a component.

To define a state variable called count that defaults to a value of 0:

const [count, setCount] = React.useState(0); // The useState argument is the default value.

The useState function returns a two element array that we destructure into a getter and a setter.

console.log(count); // Access the state via the getter.
setCount(42); // Update the state via the setter.

Clickety Clicker

Now that we know about useState let’s build a click counter. We’ll use state to keep track of the count:

See the Pen BajKWxe by Kyle Geske (@stungeye) on CodePen.

👆 The button includes an inline onClick handler that increments the count using setCount.

📢 Note: Outside of CodePen, React apps will often import useState separately from the React object:

import React, { useState } from 'react';

Allowing useState to be accessed directly:

const [count, setCount] = useState(0); 

Immutable State

It’s important to note that component state in React is immutable.

When something is immutable, it means it cannot be changed.

State variables in React cannot be mutated. Instead we must render a new version of the component with new state.

This means we could not modify the count state directly in our previous example using:

count++; // This would not work.
count = count + 1; // Neither would this.

Instead we used the setter provided by the useState hook:

setCount(count + 1); // Set as one more than the current value of count.

Once a setter has been used the component will re-render with a new immutable version of the state.

Upboat Downboat

Here’s a component with a count state variable which is set via three different event handlers:

See the Pen Up and Down Counter React by Kyle Geske (@stungeye) on CodePen.

Forms in React

We can turn form inputs into “controlled components” by binding them to state using an onChange event handler and a value attribute.

See the Pen Mirror Mirror React by Kyle Geske (@stungeye) on CodePen.

👆 Changes to the input text will trigger the onChange handler which will set the text state with setState.

⚠️ Warning: The input cannot be update via code unless the value attribute is bound to the state.

Styling Components

There are many different ways to style React components.

Four common ways are:

  1. Define styles in separate CSS documents and refer to them using JSX className attributes.
  2. Add inline styles to JSX elements.
  3. Use a CSS-in-JS library.
  4. CSS Modules

We’ll explore the first two of these styling options. See the resources below for links to details on the other two.

Resources

ClassName Styling with .css Files

Here we have a toggle button with Boolean state that we use to set its className:

See the Pen XWXpYxj by Kyle Geske (@stungeye) on CodePen.

👆 Check the CSS tab to see the two class definitions.

📢 Note: Examples in these notes have additional styles applied by MVP.css, which is included via the CodePen CSS settings.

In the above example the button’s flat look, rounded corners, white text, and hover effect, were added by MVP.css.

Only the orange/purple toggle is controlled by the component via the className attribute.

Inline JSX Styles

Styles can be define as Javascript objects and applied using a style attribute:

See the Pen Inline Styling React by Kyle Geske (@stungeye) on CodePen.

⚠️ Warning: This is not actually inline CSS. It’s Javascript.

Dynamic Inline Styles

Inline styles can be combined with state and events to create dynamic styles:

See the Pen QWydBVG by Kyle Geske (@stungeye) on CodePen.

👆 In this example we’re using state to keep track of the mouse’s position. The background colour of the button is dynamically defined based on the x and y location of the mouse.

In handleMouseMovement the x and y position of the mouse is adjusted to reflects a value from 0 to 255 within the button.

⚠️ Warning: This example may not work on mouse-less devices like phones and tablets.

Fetching Data

Loading data from a JSON file URL or an HTTP API can be integrated into a component using the useEffect hook:

See the Pen Fetching Dogs with React by Kyle Geske (@stungeye) on CodePen.

📢 Note:

  • The first argument of React.useEffect is a callback function that fetches data and sets state.
  • If the second argument is an empty array (like above) the callback will only execute when the component first mounts.
  • Without this optional second argument the callback will execute with every update.

Resources

What's Next?

There’s so much more to learn about React.

From here you might want to explore more React concepts:

And check out these complimentary tools and frameworks: