My React notes
I will share my notes from different resources about React.js for myself or for everyone else who would end up on this page.
To define a component, React lets you use two JavaScript structures: a function or a class. Before React Hooks, you would use a function when the component didn’t need any local state (you would pass it all its data via props):
You would use a class when the component needed to manage its own state, perform side effects (like loading its data or getting hands-on with the DOM), or directly respond to events:
❶ Class components set up their state in a constructor function.
❷ Class components can include methods for various stages in their life cycle.
❸ Class components have a render method that returns their UI.
1 React is evolving
React is a JavaScript library for building beautiful user interfaces. The React team wants the developer experience to be as great as possible so that developers are inspired and enabled to create delightful, productive user experiences. React Hooks in Action with Suspense and Concurrent Mode is your guide to some of the latest additions to the library, additions that can simplify your code, improve code reuse, and help make your applications slicker and more responsive, leading to happier developers and happier users.
This chapter gives a brief overview of React and its new features to whet your appetite for the details that follow later in the book.
1.1 What is React?
Say you are creating a user interface (UI) for the web, the desktop, for a smartphone, or even for a virtual reality (VR) experience. You want your page or app to display a variety of data that changes over time, like authenticated user info, filterable product lists, data visualization, or customer details. You expect the user to interact with the app, choosing filters and data sets and customers to view, filling in form fields, or even exploring a VR space! Or maybe your app will consume data from a network or from the internet, like social media updates, stock tickers, or product availability. React is here to help.
React makes it easy to build user interface components that are composable and reusable and that react to changes in data and to user interactions. A page from a social media site includes buttons, posts, comments, images, and video, among many other interface components. React helps update the interface as the user scrolls down the page, opens up posts, adds comments, or transitions to other views. Some components on the page might have repeated subcomponents, page elements with the same structure but different content. And those subcomponents could be made up of components too! There are image thumbnails, repeated buttons, clickable text, and icons aplenty. Taken as a whole, the page has hundreds of such elements. But by breaking such rich interfaces into reusable components, development teams can more easily focus on specific areas of functionality and put the components to use on multiple pages.
Making it easy to define and reuse components, and compose them into complex but understandable and usable interfaces is one of React’s core purposes. Other frontend libraries are out there (like AngularJS, Vue.js, and Ember.js), but this is a React book, so we concentrate on how React approaches components, data flow, and code reuse.
Over the next few sections, we take a high-level look at how React helps developers build such apps, highlighting five of its key features:
- Building UI from reusable, composable components
- Describing UI by using JSX—a blend of HTML-style templating and JavaScript
- Making the most of JavaScript without introducing too many idiomatic constraints
- Intelligently synchronizing state and UI
- Helping manage the fetching of code, assets, and data
1.1.1 Building a UI from components
Social media sites show rich, hierarchical, multilayered user interfaces that React can help you design and code. But for now, let’s start with something a bit simpler to get a feel for the features of React.
Say you want to build a quiz app to help learners test themselves on facts they’ve been studying. Your component should be able to show and hide questions, and show and hide answers. One question-and-answer pair might look something like figure 1.1.

Figure 1.1 Part of a quiz app showing a question and an answer
You could create a component for the question section and a component for the answer section. But the structure of the two components is the same: each has a title, some text to show and hide, and a button to do the showing and hiding. React makes it easy to define a single component, say a TextToggle
component, that you can use for both the question and the answer. You pass the title and text and whether the text should be shown to each of your TextToggle
components. You pass the values as properties (or props), something like this:
<TextToggle title="Question" text="Who created JavaScript?" show={true} /> <TextToggle title="Answer" text="Brendan Eich" show={false} />
Wait! What now? Is that HTML? XML? JavaScript? Well, programming with React is programming in JavaScript. But React provides an HTML-like syntax for describing your UI called JSX. Before running your app, the JSX needs to be preprocessed to convert it into the actual JavaScript that creates the elements of your user interface. At first it seems a bit strange, mixing HTML with your JavaScript, but it turns out the convenience is a big plus. And once your code finally runs in the browser (or other environment), it really is just JavaScript. A package called Babel is almost always used to compile the code you write into the code that will run. You can find out more about Babel at https://babeljs.io.
This chapter offers only a high-level overview of React, so we won’t explore JSX any further here. It’s worth mentioning up front, though, because it’s a widely used part of React development. In fact, in my opinion, React’s JavaScriptiness is one of its appeals—although other opinions are available—and, for the most part, it doesn’t introduce many constraints. While best practices have emerged and continue to do so, being a good JavaScript programmer and being a good React programmer are very similar skills.
So, say you’ve created the TextToggle
component; what’s next? With React, you can define new components made up of existing components. You can encapsulate the question card, showing the question and the answer, as its own QuestionCard
component. And if you want to show multiple questions at once, your Quiz
component UI could be made up of multiple QuestionCard
components.
Figure 1.2 shows two QuestionCard
components making up a Quiz
component. The Quiz
component is a container for the QuestionCard
s and has no visible presence apart from the cards it contains.

Figure 1.2 Quiz
component showing two QuestionCard
components
So, the Quiz
component is made up of QuestionCard
components, and they, in turn, are made up of TextToggle
components, which are made up of standard HTML elements—an h2
, a p
, and a button
, for example. Ultimately, the Quiz
component comprises all native UI elements. Figure 1.3 shows the simple hierarchy for your Quiz
component.

Figure 1.3 Quiz
component hierarchy
React makes this component creation and composition much easier. And once you’ve crafted your components, you can reuse them and share them easily, too. Imagine a learning resource site with different pages for different topics. On each page, you could include your Quiz
component, just passing it the quiz data for that topic.
Many React components are available to download in package management repositories like npm. There’s no need to re-create common use cases, simple or complex, when well-used, well-tested examples of drop-down menus, date pickers, rich text editors, and probably quiz templates, also, are ready and waiting to be used.
React also provides mechanisms and patterns for passing your app’s data to the components that need them. In fact, that synchronization, of state and UI, goes to the heart of what React is and what it does.
1.1.2 Synchronizing state and UI
React keeps an app’s user interface synchronized with its data. The data held in your app at any moment is called the app’s state and might include, for example, current posts, details about the logged-in user, whether comments are shown or hidden, or the content of a text input field. If new data arrives over the network or a user updates a value via a button or text input, React works out what changes need to be made to the display and efficiently updates it.
React intelligently schedules the order and timing of the updates to optimize the perceived performance of your app and improve the user experience. Figure 1.4 represents this idea, that React responds to a change in a component’s state by re-rendering the user interface.

Figure 1.4 When a value in a component’s state changes, React re-renders the user interface.
But updating state and re-rendering is not a one-off task. A visitor using your app is likely to cause a multitude of state changes, and React will need to repeatedly ask your components for the latest UI that represents those latest state values. It’s your components’ job to convert their state and props (the properties passed to them) into a description of their user interface. React then takes those UI descriptions and schedules updates to the browser’s Document Object Model (DOM) where necessary.
CYCLE DIAGRAMS
To represent the ongoing cycle of state changes and UI updates, this book uses circular cycle diagrams to illustrate the interactions between your components and React. Figure 1.5 is a simple example, showing how React calls your component code when the component first appears and when a user updates a value.

Figure 1.5 React calls and re-calls your component to generate a description of its UI using the latest state.
The cycle diagrams are accompanied by tables, like table 1.1, describing the diagrams’ steps in more detail. The diagram and table pair don’t necessarily cover everything that is happening but pull out the key steps to help you understand the similarities and differences related to the way components work in different scenarios.
For example, this section’s figure doesn’t show how the event handler works with React to update the state; that detail is added in later diagrams when introducing the relevant React Hooks.
Table 1.1 Some key steps when React calls and re-calls a function component
Step | What happens? | Discussion |
---|---|---|
1 | React calls the component. | To generate the UI for the page, React traverses the tree of components, calling each one. React will pass each component any props set as attributes in the JSX. |
2 | The component specifies an event handler. | The event handler may listen for user clicks, timers firing, or resources loading, for example. The handler will change the state when it runs later. React will hook up the handler to the DOM when it updates the DOM in step 4. |
3 | The component returns its UI. | The component uses the current state value to generate its user interface and returns it, finishing its work. |
4 | React updates the DOM. | React compares the description of the UI the component returns with the current description of the app’s UI. It efficiently makes any necessary changes to the DOM and sets up or updates event handlers as necessary. |
5 | The event handler fires. | An event fires, and the handler runs. The handler changes the state. |
6 | React calls the component. | React knows the state value has changed so must recalculate the UI. |
7 | The component specifies an event handler. | This is a new version of the handler and may use the newly updated state value. |
8 | The component returns its UI. | The component uses the current state value to generate its user interface and returns it, finishing its work. |
9 | React updates the DOM. | React compares the description of the UI the component returns with the previous description of the app’s UI. It efficiently makes any necessary changes to the DOM and sets up or updates event handlers as necessary. |
The illustrations also use consistent icons to represent key objects and actions discussed in the surrounding text, such as components, state values, event handlers, and UI.
STATE IN THE QUIZ APP
Social media pages, like the one discussed at the start of the chapter, usually require a lot of state, with new posts being loaded and users liking posts, adding comments, and interacting with components in a variety of ways. Some of that state, like the current user, may be shared across many components, whereas other state, like a comment, may be local to a post.
In the Quiz app, you have a question-and-answer component, a QuestionCard
, shown again in figure 1.6. Users can show and hide each question and answer and move to the next available question.

Figure 1.6 The question-and-answer component with the answer hidden
The QuestionCard
component state includes the information needed to display the current question and answer:
- The question number
- The number of questions
- The question text
- The answer text
- Whether the question is hidden or shown
- Whether the answer is hidden or shown
Clicking the answer’s Show button changes the state of the component. Maybe an isAnswerShown
variable switches from false
to true
. React will notice that the state has changed, will update the displayed component to show the answer text, and toggle the button’s text from Show to Hide (figure 1.7).

Figure 1.7 The question-and-answer component with the answer shown
Clicking the Next button changes the question number. It will switch from question 1 to question 2, as shown in figure 1.8. If the questions and answers for the whole quiz are in memory, React can update the display straightaway. If they need to be loaded from a file or service, React can wait while the data is being fetched before updating the UI or, if the network is slow, show a loading indicator like a spinner.

Figure 1.8 The question-and-answer component showing the second question. The answer has been hidden.
The simple Quiz app example doesn’t need much state to perform its duties. Most real-world apps are more complicated. Deciding where state should live—whether a component should manage its own state, whether some components should share state, and whether some state should be globally shared—is an important part of building apps. React provides mechanisms for all three scenarios, and published packages, like Redux, MobX, React Query, and Apollo Client, for example, offer approaches to manage state via a data store outside your components.
In the past, whether or not your component managed some of its own state determined the method of component creation you would use; React provides two main methods: function components and class components, as discussed in the next section.
1.1.3 Understanding component types
To define a component, React lets you use two JavaScript structures: a function or a class. Before React Hooks, you would use a function when the component didn’t need any local state (you would pass it all its data via props):
function MyComponent (props) { // Maybe work with the props in some way. // Return the UI incorporating prop values. }
You would use a class when the component needed to manage its own state, perform side effects (like loading its data or getting hands-on with the DOM), or directly respond to events:
class MyComponent extends React.Component { constructor (props) { super(props); this.state = { // Set up state here. ❶ }; } componentDidMount () { // Perform a side effect like loading data. ❷ } render () { // Return the UI using prop values and state. ❸ } }
❶ Class components set up their state in a constructor function.
❷ Class components can include methods for various stages in their life cycle.
❸ Class components have a render method that returns their UI.
The addition of React Hooks means you can now use function components to manage state and side effects:
function MyComponent (props) { // Use local state. const [value, setValue] = useState(initialValue); ❶ const [state, dispatch] = useReducer(reducer, initialState); ❶ useEffect(() => { // Perform side effect. ❷ }); return ( <p>{value} and {state.message}</p> ❸ ); }
❶ Use hooks to manage state.
❷ Use hooks to manage side effects.
❸ Return UI directly from the function.