VDone Demo VDone Demo
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)

Nikolay Tuzov

Backend Developer
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)
  • 核心概念

    • Introduction to JSX
    • Rendering Elements
    • Components & Props
    • State & Lifecycle
      • Converting a Function Component to a Class Component
      • Adding Local State to a Class Component
      • Adding Lifecycle Methods to a Class
      • Using State Correctly
        • Do Not Modify State Directly
        • State Updates May Be Asynchronous
        • State Updates are Merged
      • The Data Flows Down (Unidirectional Data Flow)
        • Each component is truly isolated.
    • Handling Events
    • Conditional Rendering
    • Lists & Keys
    • Forms
    • Lifting State Up (Shared State)
    • Composition vs Inheritance
    • Thinking in React
  • 高级指引

  • Hook

  • 案例演示

  • 《React》笔记
  • 核心概念
xugaoyi
2021-03-24
Contents

State & Lifecycle

# 04. State & Lifecycle

State is similar to props, but state is private and fully controlled by the component.

State is similar to the data option in Vue.

# Converting a Function Component to a Class Component

Before the useState hook, state was managed through class components?

class Clock extends React.Component {
  render() {
    return (
    	<div>
      	<h1>Hello, world</h1>
        <h2>It is {this.props.date.toLocalTimeString()}</h2>
      </div>
    )
  }
}
1
2
3
4
5
6
7
8
9
10

Each time the component updates, the render method is called, but as long as we render <Clock /> into the same DOM node, only a single instance of the Clock class will be created and used. This lets us use additional features such as state and lifecycle methods.

Singleton pattern?

# Adding Local State to a Class Component

class Clock extends React.Component {
  // Step 2: Add a constructor and assign initial value to this.state
  constructor(props) {
    super(props) // Pass props to the parent class constructor via super
    this.state = {date: new Date()}
  }
  render() {
    // Step 1: Replace this.props with this.state in the render method
    return (
    	<div>
      	<h1>Hello, world</h1>
        <h2>It is {this.state.date.toLocalTimeString()}</h2>
      </div>
    )
  }
}


ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Adding Lifecycle Methods to a Class

In applications with many components, it's very important to free up resources taken by the components when they are destroyed.

When the Clock component is first rendered to the DOM, we want to set up a timer (opens new window). This is called "mounting" in React.

Likewise, when the DOM produced by the Clock is removed, we want to clear that timer (opens new window). This is called "unmounting" in React.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  // Mount - runs after mounting is complete
  componentDidMount() {
    // Start a timer after the component mounts
    this.timerID = serInterval( // You can add arbitrary property fields to this
    	() => this.tick(), 1000
    )
  }

  // Unmount
  componentWillUnmount() {
    // Clear the timer after the component unmounts to free memory
    clearInterval(this.timerID)
  }

  tick() {
    this.setState({
      date: new Date()
    })
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# Using State Correctly

There are three things you should know about setState():

# Do Not Modify State Directly


// Wrong: do not modify state directly
this.state.comment = 'Hello'

// Correct: use setState()
this.setState({comment: 'Hello'})
1
2
3
4
5
6

The constructor is the only place where you can directly assign to this.state.

Is setState a React internal method that makes state updates reactive?

# State Updates May Be Asynchronous

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

To fix this, use a form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
1
2
3
4

# State Updates are Merged

When you call setState(), React merges the object you provide into the current state.

  constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

// Calling setState separately to update individual state properties
 componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

The merging is shallow, so this.setState({comments}) leaves this.state.posts intact, but completely replaces this.state.comments.

# The Data Flows Down (Unidirectional Data Flow)

Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn't care whether it is defined as a function or a class.

This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.

A component may choose to pass its state down as props to its child components:

<FormattedDate date={this.state.date} />
1

The FormattedDate component would receive the date in its props and wouldn't know whether it came from the Clock's state, from the Clock's props, or was typed by hand.

This is commonly called a "top-down" or "unidirectional" data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components "below" them in the tree.

If you imagine a component tree as a waterfall of props, each component's state is like an additional water source that joins it at an arbitrary point but also flows down.

# Each component is truly isolated.

Edit (opens new window)
#React
Last Updated: 2026/03/21, 12:14:36
Components & Props
Handling Events

← Components & Props Handling Events→

Recent Updates
01
How I Discovered Disposable Email — A True Story
06-12
02
Animations in Grid Layout
09-15
03
Renaming a Git Branch
08-11
More Articles >
Theme by VDone | Copyright © 2026-2026 Nikolay Tuzov | MIT License | Telegram
  • Auto
  • Light Mode
  • Dark Mode
  • Reading Mode