Khắc phục lỗi onpress this.setstate state3 a react native năm 2024

This page introduces the concept of state and lifecycle in a React component. You can find a detailed component API reference here.

Consider the ticking clock example from . In , we have only learned one way to update the UI. We call

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

1 to change the rendered output:

const root = ReactDOM.createRoot(document.getElementById('root'));
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);}
setInterval(tick, 1000);

Try it on CodePen

In this section, we will learn how to make the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 component truly reusable and encapsulated. It will set up its own timer and update itself every second.

We can start by encapsulating how the clock looks:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

Try it on CodePen

However, it misses a crucial requirement: the fact that the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 sets up a timer and updates the UI every second should be an implementation detail of the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2.

Ideally we want to write this once and have the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 update itself:

To implement this, we need to add “state” to the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 component.

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

Converting a Function to a Class

You can convert a function component like

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 to a class in five steps:

  1. Create an ES6 class, with the same name, that extends

    class Clock extends React.Component { render() {

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

    8.
  2. Add a single empty method to it called

    class Clock extends React.Component { render() {

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

    9.
  3. Move the body of the function into the

    class Clock extends React.Component { render() {

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

    9 method.
  4. Replace

    class Clock extends React.Component { render() {

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

    1 with

    class Clock extends React.Component { render() {

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

    2 in the

    class Clock extends React.Component { render() {

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

    9 body.
  5. Delete the remaining empty function declaration.

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

Try it on CodePen

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 is now defined as a class rather than a function.

The

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

5 method will be called each time an update happens, but as long as we render

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

6 into the same DOM node, only a single instance of the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 class will be used. This lets us use additional features such as local state and lifecycle methods.

Adding Local State to a Class

We will move the

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

8 from props to state in three steps:

  1. Replace

    class Clock extends React.Component { render() {

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

    9 with

    class Clock extends React.Component { constructor(props) {

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

    0 in the

    class Clock extends React.Component { render() {

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

    9 method:

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

  1. Add a that assigns the initial

    class Clock extends React.Component { constructor(props) {

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

    2:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

Note how we pass

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

1 to the base constructor:

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

Class components should always call the base constructor with

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

1.

  1. Remove the

    class Clock extends React.Component { render() {

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

    8 prop from the

    class Clock extends React.Component { render() {

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

    6 element:

We will later add the timer code back to the component itself.

The result looks like this:

class Clock extends React.Component {
  constructor(props) {    super(props);    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>
    );
  }
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);

Try it on CodePen

Next, we’ll make the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 set up its own timer and update itself every second.

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.

We want to set up a timer whenever the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 is rendered to the DOM for the first time. This is called “mounting” in React.

We also want to clear that timer whenever the DOM produced by the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 is removed. This is called “unmounting” in React.

We can declare special methods on the component class to run some code when a component mounts and unmounts:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

These methods are called “lifecycle methods”.

The

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

0 method runs after the component output has been rendered to the DOM. This is a good place to set up a timer:

  componentDidMount() {
    this.timerID = setInterval(      () => this.tick(),      1000    );  }

Note how we save the timer ID right on

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

1 (

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

2).

While

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

2 is set up by React itself and

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 has a special meaning, you are free to add additional fields to the class manually if you need to store something that doesn’t participate in the data flow (like a timer ID).

We will tear down the timer in the

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

5 lifecycle method:

  componentWillUnmount() {
    clearInterval(this.timerID);  }

Finally, we will implement a method called

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

6 that the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 component will run every second.

It will use

  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }

8 to schedule updates to the component local state:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

0

Try it on CodePen

Now the clock ticks every second.

Let’s quickly recap what’s going on and the order in which the methods are called:

  1. When

    class Clock extends React.Component { render() {

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

    6 is passed to

    class Clock extends React.Component { render() {

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

    1, React calls the constructor of the

    class Clock extends React.Component { render() {

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

    2 component. Since

    class Clock extends React.Component { render() {

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

    2 needs to display the current time, it initializes

    class Clock extends React.Component { constructor(props) {

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

    2 with an object including the current time. We will later update this state.
  2. React then calls the

    class Clock extends React.Component { render() {

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

    2 component’s

    class Clock extends React.Component { render() {

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

    9 method. This is how React learns what should be displayed on the screen. React then updates the DOM to match the

    class Clock extends React.Component { render() {

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

    2’s render output.
  3. When the

    class Clock extends React.Component { render() {

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

    2 output is inserted in the DOM, React calls the

    constructor(props) {

    super(props);    this.state = {date: new Date()};  
    
    }

    0 lifecycle method. Inside it, the

    class Clock extends React.Component { render() {

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

    2 component asks the browser to set up a timer to call the component’s

    constructor(props) {

    super(props);    this.state = {date: new Date()};  
    
    }

    6 method once a second.
  4. Every second the browser calls the

    constructor(props) {

    super(props);    this.state = {date: new Date()};  
    
    }

    6 method. Inside it, the

    class Clock extends React.Component { render() {

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

    2 component schedules a UI update by calling

    class Clock extends React.Component { constructor(props) {

    super(props);  
    this.state = {date: new Date()};  
    
    } componentDidMount() { } componentWillUnmount() { } render() {
    return (  
      <div>  
        <h1>Hello, world!</h1>  
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>  
      </div>  
    );  
    
    } }

    3 with an object containing the current time. Thanks to the

    class Clock extends React.Component { constructor(props) {

    super(props);  
    this.state = {date: new Date()};  
    
    } componentDidMount() { } componentWillUnmount() { } render() {
    return (  
      <div>  
        <h1>Hello, world!</h1>  
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>  
      </div>  
    );  
    
    } }

    3 call, React knows the state has changed, and calls the

    class Clock extends React.Component { render() {

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

    9 method again to learn what should be on the screen. This time,

    class Clock extends React.Component { constructor(props) {

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

    0 in the

    class Clock extends React.Component { render() {

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

    9 method will be different, and so the render output will include the updated time. React updates the DOM accordingly.
  5. If the

    class Clock extends React.Component { render() {

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

    2 component is ever removed from the DOM, React calls the

    constructor(props) {

    super(props);    this.state = {date: new Date()};  
    
    }

    5 lifecycle method so the timer is stopped.

Using State Correctly

There are three things you should know about

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3.

Do Not Modify State Directly

For example, this will not re-render a component:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

1

Instead, use

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

2

The only place where you can assign

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 is the constructor.

State Updates May Be Asynchronous

React may batch multiple

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3 calls into a single update for performance.

Because

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

2 and

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 may be updated asynchronously, you should not rely on their values for calculating the next state.

For example, this code may fail to update the counter:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

3

To fix it, use a second form of

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3 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:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

4

We used an arrow function above, but it also works with regular functions:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

5

State Updates are Merged

When you call

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3, React merges the object you provide into the current state.

For example, your state may contain several independent variables:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

6

Then you can update them independently with separate

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

3 calls:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

7

The merging is shallow, so

  componentDidMount() {
    this.timerID = setInterval(      () => this.tick(),      1000    );  }

9 leaves

  componentWillUnmount() {
    clearInterval(this.timerID);  }

0 intact, but completely replaces

  componentWillUnmount() {
    clearInterval(this.timerID);  }

1.

The Data Flows Down

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:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

8

The

  componentWillUnmount() {
    clearInterval(this.timerID);  }

2 component would receive the

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

8 in its props and wouldn’t know whether it came from the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2’s state, from the

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2’s props, or was typed by hand:

const root = ReactDOM.createRoot(document.getElementById('root'));
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  root.render(<Clock date={new Date()} />);}
setInterval(tick, 1000);

9

Try it on CodePen

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.

To show that all components are truly isolated, we can create an

  componentWillUnmount() {
    clearInterval(this.timerID);  }

6 component that renders three

  componentWillUnmount() {
    clearInterval(this.timerID);  }

7s:

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

0

Try it on CodePen

Each

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2 sets up its own timer and updates independently.

In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa.