2025-11-29
ReactJS
00
请注意,本文编写于 233 天前,最后修改于 232 天前,其中某些信息可能已经过时。

目录

Think in React
installation
create a React app
next.js
React Router
Build a React app from Scratch
Add React to an Existing project
using typescript
Useful Types
React Compiler
Descripe UI
Your first component
Writing Markup with JSX
JavaScript in JSX with Curly Braces
Passing props to a component
Conditional Rendering
Rendering Lists
Keeping Components Pure
Local mutation: Your component’s little secret
Understanding Your UI as a Tree
Adding Interactivity
Responding to Events
State: A Component's Memory
Render and Commit

It's been a long time since I wrote a technical article about React, and React has also released its latest version, 19. Today I reread the official React website. Record the key points and new things I've learned.

This article is a personal note, reflecting my own gaps in understanding React, so it is not recommended for reading.

Think in React

  • When you build a user interface with React, you will first break it apart into pieces called components.
  • Then, you will describe the different visual states for each of your components.
  • Finally, you will connect your components together so that the data flows through them.
--
small projectsit’s usually easier to go top-down
larger projectsit’s easier to go bottom-up.

Which of these are state? Identify the ones that are not:

  • Does it remain unchanged over time? If so, it isn’t state.
  • Is it passed in from a parent via props? If so, it isn’t state.
  • Can you compute it based on existing state or props in your component? If so, it definitely isn’t state!

Props vs State

  • Props are like arguments you pass to a function.
  • State is like a component’s memory.

one-way data flow, the data flows down from top-level component to the ones at the bottom of the tree.

How to identify where your state should live?

  • Identify every component that renders something based on that state.
  • Find their closest common parent component—a component above them all in the hierarchy.
  • Decide where the state should live.

installation

Create React App has been deprecated. For more information, see Sunsetting Create React App.

create a React app

next.js

next.js is a full-stack framework

  • support all the features you need to deploy and scale your app in production.
  • do not require a server. CSR/SPA/SSG
    • you can start with a client-only app, and later,you can opt-in to using server features on individual routes without rewriting your app.
  • Next.js also supports static export which doesn’t require a server.
Next.js’s App Router bundler fully implements the official React Server Components specification
  • This lets you mix build-time, server-only, and interactive components in a single React tree.
  • Next.js’s App Router also integrates data fetching with Suspense.

React Router

React Router is the most popular routing library for React and can be paired with Vite to create a full-stack React framework.

Next.js’s App Router bundler fully implements the official React Server Components specification

Build a React app from Scratch

Routing

  • Routers can be configured within your code, or defined based on your component folder and file structures.
  • need to handle nested routes, route parameters, and query parameters
  • usually integrated with data fetching, code splitting, and page rendering approaches
  • We suggest using React Router, Tanstack Router

Data Fetching

  • requires handling loading states, error states, and caching the fetched data
  • categories
    • Purpose-built data fetching libraries
    • be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well.

Q: Why React recommends prefetching data in router loaders ?

A: for faster pre-fetching and better performance,
fetching data directly in components can lead to slower loading times due to network request waterfalls.

mitigate slow loading

  • Caching,
  • reducing features/dependencies,
  • move some code to run on the server

Splitting code by route, when integrated with bundling and data fetching, can reduce the initial load time of your app

Q: What's the different between SSR and RSC

-SSRRSC
definitionServer-Side RenderingReact Server Components
GoalGenerate a fully rendered HTML page on the server for initial page load (to improve SEO, performance, and user experience)Split component execution between server and client to reduce client bundle size and improve performance (especially on slow devices/ networks).
Key focus:Solves the "empty white screen" problem
improves SEO
Offload heavy work (e.g., data fetching, large libraries) to the server, so the client downloads less JavaScript.
critical distinctionRuns all components on the server during initial load. Client-side hydration runs all components again (in the browser) to add interactivity.Runs server components only on the server (never sent to the client). Client components run only in the browser (sent as JS bundles).
Data FetchingData fetching happens on the server (during initial render) to populate the HTML.Data fetching happens directly in server components (on the server), at the component level.
Bundle SizeThe client downloads the entire JavaScript bundle for the app (since hydration requires re-rendering all components)The client downloads only client components (marked 'use client'). Server components are not sent to the client (their code stays on the server).

Add React to an Existing project

  1. use React for an entire subroute

  2. Using React for a part of your existing page

split your code into modules with the import / export syntax, and use packages (for example, React) from the npm package registry.

using typescript

Useful Types

There is quite an expansive set of types which come from the @types/react package

You can find them in React’s folder in DefinitelyTyped. We will cover a few of the more common types here.

There are many types of events provided in the React types - the full list can be found here which is based on the most popular events from the DOM.

If you need to use an event that is not included in this list, you can use the React.SyntheticEvent type, which is the base type for all events.

two common paths to describing the children of a component

  • to use the React.ReactNode type
  • to use the React.ReactElement type

the difference between React.ReactNode and React.ReactElement

Style Props

React.CSSProperties

Further learning

React Compiler

TODO

Descripe UI

JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information.

a converter: transform HTML into JSX

Keeping components pure

A pure function:

  • Minds its own business. It does not change any objects or variables that existed before it was called.
  • Same inputs, same output. Given the same inputs, a pure function should always return the same result.

Your first component

The names of React components must start with a capital letter or they won’t work!

JSX pitfall: Without parentheses, any code on the lines after return will be ignored!

pitfall

  • Components can render other components, but you must never nest their definitions. When a child component needs some data from a parent, pass it by props instead of nesting definitions.

summary

  • React lets you create components, reusable UI elements for your app.
  • In a React app, every piece of UI is a component.
  • React components are regular JavaScript functions except:
    • Their names always begin with a capital letter.
    • They return JSX markup.

Writing Markup with JSX

JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside a JavaScript file.

As the Web became more interactive, logic increasingly determined content. JavaScript was in charge of the HTML! This is why in React, rendering logic and markup live together in the same place—components.

Keeping a button’s rendering logic and markup together ensures that they stay in sync with each other on every edit.

JSX and React are two separate things. They’re often used together, but you can use them independently of each other. JSX is a syntax extension, while React is a JavaScript library.

JSX is stricter and has a few more rules than HTML

  • must be wrapped in an enclosing tag
  • Close all the tags
  • camelCase all most of the things!
    • for --> htmlFor
    • class --> className
    • strick-width --> strickWidth
  • Pitfall: For historical reasons, aria-* and data-* attributes are written as in HTML with dashes.

Pro-tip: We recommend using a converter to translate your existing HTML and SVG to JSX.

Why do multiple JSX tags need to be wrapped?
JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can’t return two objects from a function without wrapping them into an array. This explains why you also can’t return two JSX tags without wrapping them into another tag or a Fragment.

JavaScript in JSX with Curly Braces

Where to use curly braces?
You can only use curly braces in two ways inside JSX:

  • As text directly inside a JSX tag: <h1>{name}'s To Do List</h1> works, but <{tag}>Gregorio Y. Zara's To Do List</{tag}> will not.
  • As attributes immediately following the = sign: src={avatar} will read the avatar variable, but src="{avatar}" will pass the string "{avatar}".

double curlies just means pass objects in JSX

Pitfall

Inline style properties are written in camelCase.

For example, HTML <ul style="background-color: black"> would be written as <ul style={{ backgroundColor: 'black' }}> in your component.

Now you know almost everything about JSX:

  • JSX attributes inside quotes are passed as strings.
  • Curly braces let you bring JavaScript logic and variables into your markup.
  • They work inside the JSX tag content or immediately after = in attributes.
  • {{ and }} is not special syntax: it’s a JavaScript object tucked inside JSX curly braces.

Forwarding props with the JSX spread syntax, is conciseness

Passing props to a component

props are immutable

  • To pass props, add them to the JSX, just like you would with HTML attributes.
  • To read props, use the function Avatar({ person, size }) destructuring syntax.
  • You can specify a default value like size = 100, which is used for missing and undefined props.
  • You can forward all props with <Avatar {...props} /> JSX spread syntax, but don’t overuse it!
  • Nested JSX like <Card><Avatar /></Card> will appear as Card component’s children prop.
  • Props are read-only snapshots in time: every render receives a new version of props.
  • You can’t change props. When you need interactivity, you’ll need to set state.

Conditional Rendering

In React, you can conditionally render JSX using JavaScript syntax like if statements, &&, and ? : operators.

Conditionally returning nothing with null . More often, you would conditionally include or exclude the component in the parent component’s JSX.

Conditional (ternary) operator (? :)

Logical AND operator (&&)

Pitfall

  • React considers false as a “hole” in the JSX tree, just like null or undefined, and doesn’t render anything in its place.
  • 0 is also a falsy value

Conditionally assigning JSX to a variable

Recap

  • In React, you control branching logic with JavaScript.
  • You can return a JSX expression conditionally with an if statement.
  • You can conditionally save some JSX to a variable and then include it inside other JSX by using the curly braces.
  • In JSX, {cond ? <A /> : <B />} means “if cond, render <A />, otherwise <B />”.
  • In JSX, {cond && <A />} means “if cond, render <A />, otherwise nothing”.
  • The shortcuts are common, but you don’t have to use them if you prefer plain if.

Rendering Lists

When and why to use React keys?

  • when: rendering a list
  • why: They let us uniquely identify an item between its siblings. and React will reuse the nodes by their keys.

Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen key helps React infer what exactly has happened, and make the correct updates to the DOM tree.

What do you do when each item needs to render not one, but several DOM nodes?

The short <>...</> Fragment syntax won’t let you pass a key, so you need to either group them into a single <div>, or use the slightly longer and more explicit <Fragment> syntax:

Pitfall

  • if you don’t specify a key, React will use index.
  • if an item is inserted, deleted, or if the array gets reordered, the items will not resued
  • Similarly, do not generate keys on the fly, e.g. with key={Math.random()}.
    • this will lead to all your components and DOM being recreated every time.
  • Note that your components won’t receive key as a prop. It’s only used as a hint by React itself. If your component needs an ID, you have to pass it as a separate prop: <Profile key={id} userId={id} />.

Keeping Components Pure

Why should we keeping components pure ?

Pure functions only perform a calculation and nothing more.
By strictly only writing your components as pure functions, you we avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows.

To get these benefits, though, there are a few rules you must follow.

  • Purity: Components as formulas
    • It minds its own business. It does not change any objects or variables that existed before it was called.
    • Same inputs, same output.

React assumes that every component you write is a pure function.

  • Side Effects: (un)intended consequences

Detecting impure calculations with StrictMode

  • You should always treat props, state, and context as read-only.
  • When you want to change something in response to user input, you should set state instead of writing to a variable.
  • React offers a “Strict Mode” in which it calls each component’s function twice during development. By calling the component functions twice, Strict Mode helps find components that break these rules.
  • Strict Mode has no effect in production,

Local mutation: Your component’s little secret

if you can’t find the right event handler for your side effect, you can use useEffect. However, this approach should be your last resort.

if you can’t find the right event handler for your side effect, you can use useEffect. However, this approach should be your last resort.

Why does React care about purity? Writing pure functions takes some habit and discipline. But it also unlocks marvelous opportunities:
  • Your components could run in a different environment
  • You can improve performance by skipping rendering components whose inputs have not changed.
  • If some data changes in the middle of rendering a deep component tree, React can restart rendering without wasting time to finish the outdated render. Purity makes it safe to stop calculating at any time.
Every new React feature we’re building takes advantage of purity. From data fetching to animations to performance, keeping components pure unlocks the power of the React paradigm.

Recap

  • A component must be pure, meaning:
    • It minds its own business. It should not change any objects or variables that existed before rendering.
    • Same inputs, same output.
  • Rendering can happen at any time, so components should not depend on each others’ rendering sequence.
  • You should not mutate any of the inputs that your components use for rendering. That includes props, state, and context. To update the screen, “set” state instead of mutating preexisting objects.
  • Strive to express your component’s logic in the JSX you return. When you need to “change things”, you’ll usually want to do it in an event handler. As a last resort, you can useEffect.
  • Writing pure functions takes a bit of practice, but it unlocks the power of React’s paradigm.

Understanding Your UI as a Tree

React use a tree to keep track of your app’s component structure.

Trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size.

Module Dependency Tree

Dependency trees are useful to determine what modules are necessary to run your React app.

When building a React app for production, a tool which is called a bundler, will use the dependency tree to determine what modules should be included.

Adding Interactivity

Q: What is state in React?
A: In React, data that changes over time is called state.

use immer.js

js
import { useImmer } from 'use-immer'; export default function Form() { const [person, updatePerson] = useImmer({ name: 'Jack', // ... }); function handleNameChange(e) { updatePerson(draft => { draft.name = e.target.value; }); } return ( <> <label> Name: <input value={person.name} onChange={handleNameChange} /> </label> <p> {person.name} <br /> is in Beijing </p> </> ); }

Responding to Events

Pitfall

All events propagate in React except onScroll, which only works on the JSX tag you attach it to.

Additional information: Event bubbling and capture
  • Events are bubbling by default, travels upwards
  • We can use `e.stopPropagation()` to prevent the out events
  • If you want to trigger the event of the outer element first, you can use `onClickCapture`, travels down
  • Capture events are useful for code like routers or analytics, but you probably won’t use them in app code.
  • Preventing default behavior: e.preventDefault()

State: A Component's Memory

In React, this kind of component-specific memory is called state.

Precaution of Hooks

  • Hooks—functions starting with use
  • can only be called at the top level of your components or your own Hooks.
    • You can’t call Hooks inside conditions, loops, or other nested functions.
    • Only in this way, Hooks rely on a stable call order on every render of the same component.

State is isolated and private

Render and Commit

“Rendering” is React calling your components.

  • On initial render, React will call the root component.
  • For subsequent renders, React will call the function component whose state update triggered the render,

During the next step, the commit phase.

Pitfall: Rendering must always be a pure calculation

If you run into a performance issue, there are several opt-in ways to solve it described in the Performance section. Don’t optimize prematurely!

Step 3: React commits changes to the DOM

  • For the initial render, React will use the appendChild() DOM API to put all the DOM nodes it has created on screen.
  • For re-renders, React will apply the minimal necessary operations (calculated while rendering!) to make the DOM match the latest rendering output.

Recap

  • Any screen update in a React app happens in three steps:
    • Trigger
    • Render
    • Commit
  • You can use Strict Mode to find mistakes in your components
  • React does not touch the DOM if the rendering result is the same as last time

本文作者:郭郭同学

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!