React Events, State, and Style
React components are functions that returns JSX that can be customized by passing in “props”.
So far we’ve been creating components with JSX that remains unchanged once rendered.
Here we introduce the dynamic aspects of React that allow components to persist state and to react to user events.
Table of Contents
- Objective
- Reacting to Events
- Inline Event Handlers
- The Event Object
- The State of Things
- The useState Hook
- Clickety Clicker
- Immutable State
- Upboat Downboat
- Forms in React
- Styling Components
- ClassName Styling with .css Files
- Inline JSX Styles
- Dynamic Inline Styles
- Fetching Data
- What’s Next?
Objective
By the end of this module, you should be able to:
- Bind callback functions to JSX element event handlers.
- Suppress the default behaviour of an event handlers while adding your own event behaviour.
- Fetch and modify the state of a component using the getters and setters provided by the UseState hook.
- Explain the role of immutable state in React components.
- Bind component state to form inputs.
- Change the look and feel of components using CSS files and inline JSX styles.
- Fetch JSON data from a URL when a component first mounts using React’s useEffect hook.
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
- List of Officially Support Events - Includes keyboard, mouse, and touch events.
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:
-
We’ve seen that properties can be passed to components as JSX attributes. These
props
are supplied by a component’s parent. When theseprops
change the component is re-rendered based on the new data. -
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.
Resources
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:
- Define styles in separate CSS documents and refer to them using JSX
className
attributes. - Add inline styles to JSX elements.
- Use a CSS-in-JS library.
- 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.
- Style object keys must be converted from CSS hypen-style to camelCase.
- Style object values must be strings.
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:
- Thinking in React - The thought process behind building a searchable product data table using React.
- Fragments - Group JSX children without adding an extra DOM node. The short syntax is particularly nice.
- Context - Pass data through your component tree.
- Render Props and Higher Order Components - Reusable component logic.
And check out these complimentary tools and frameworks:
- React Router - Route-based component navigation.
- Redux - A state container for JS apps.
- Next.js - Popular React-based app framework.
- Gatsby - Static site generator for React.
- You might also want to explore outside the React ecosystem and look into Vue or Svelte.