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.
By the end of this module, you should be able to:
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:
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 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.
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 these props 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.
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.
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);
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.
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.
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.
There are many different ways to style React components.
Four common ways are:
className attributes.We’ll explore the first two of these styling options. See the resources below for links to details on the other two.
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.
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.
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.
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:
React.useEffect is a callback function that fetches data and sets state.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: