This blog post mainly reviews the application scenarios and examples of the state attribute.
React treats a component as a State machine. Achieve different states by interacting with the user, and then render the UI to keep the user interface and data consistent.
React simply updates the component’s state and rerenders the user interface based on the new state (don’t manipulate the DOM).
The following example creates an ES6 class with a name extension react.ponent that uses this.state in the Render () method to change the current time.
Add a class constructor to initialize the state this.state. Class components should always call the underlying constructor using props.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return( <div> <h1>Hello, world! </h1> <h2> is now {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('example'));Copy the code
Next, we’ll have Clock set its own timer and update it every second.
Adding lifecycle methods to classes In applications with many components, it is important to release resources occupied by the components when they are destroyed.
Whenever the Clock component is first loaded into the DOM, we want to generate the timer, which is called mounting in React.
Also, we want to clear the timer whenever the Clock generated DOM is removed, which is called unloading in React.
We can declare special methods on the component class to run some code when the component is mounted or unmounted:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return( <div> <h1>Hello, world! </h1> <h2> is now {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('example'));Copy the code
The componentDidMount() and componentWillUnmount() methods are called lifecycle hooks.
The componentDidMount() hook is executed after the component is exported to the DOM, and we can set a timer on that hook.
This.timerid is the timerID, which can be unmounted from the componentWillUnmount() hook.
Code execution order:
- When passed to reactdom.render (), React calls the constructor of the Clock component. Since Clock needs to display the current time, use an object containing the current time to initialize this.state. We will update this status later.
- React then calls the Render () method of the Clock component. React knows what should be displayed on the screen, and React updates the DOM to match Clock’s render output.
- React is called when the output of Clock is inserted into the DOM
componentDidMount()
Lifecycle hooks. In it, the Clock component asks the browser to set up a timer that calls tick() every second. - The browser calls the tick() method every second. Here, the Clock component schedules UI updates by calling setState() with an object containing the current time. By calling setState(), React knows that the state has changed and calls the Render () method again to determine what should be displayed on the screen. This time, the this.state.date in the render() method will be different, so the render output will contain the update time and update the DOM accordingly.
- Once the Clock component is removed from the DOM, React is called
componentWillUnmount()
The hook function, the timer will be cleared.
Data flows from the top down Neither parent nor child components know whether a component is stateful or stateless, and they should not care whether a component is defined as a function or a class.
This is why states are often referred to as local or encapsulated. Other components are not accessible except the component that owns and sets it.
In the following example, the FormattedDate component will receive the date value in its property and does not know whether it is from the Clock state, from the Clock property, or manually entered:
function FormattedDate(props) {
return< h2 > is now a {props. Date. ToLocaleTimeString ()}. < / h2 >; }class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return( <div> <h1>Hello, world! </h1> <FormattedDate date={this.state.date} />
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('example'));Copy the code
This is often referred to as top-down or one-way data flow. Any state is always owned by some particular component, and any data or UI exported from that state can only affect components down the tree.
If you imagine a tree of components as a waterfall of properties, the state of each component is like an additional water source, which is connected at an arbitrary point but also flows down.
To show that all components are truly isolated, we can create an App component that renders three clocks:
function FormattedDate(props) {
return< h2 > is now a {props. Date. ToLocaleTimeString ()}. < / h2 >; }class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return( <div> <h1>Hello, world! </h1> <FormattedDate date={this.state.date} /> </div> ); }}function App(a) {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}
ReactDOM.render(<App />, document.getElementById('example'));
Copy the code
In the example above, each Clock component has its own timer set up and updated independently.
In React applications, whether a component is stateful or stateless is considered an implementation detail of a component that may change over time.
We can use stateless components in stateful components, and we can use stateful components in stateless components.