React Component State (State)
Components can have state, which is the private part of component data and can be used to manage dynamic data.
State applies only to class components, or it can be used in function components when using React Hooks.
React treats components as state machines. Through interaction with users, different states are implemented, and then the UI is rendered to keep the user interface consistent with data.
In React, you only need to update the component's state, and then re-render the user interface based on the new state (do not manipulate the DOM).
The following example creates an ES6 class whose name extends React.Component, and uses this.state in the render() method to modify the current time.
Add a class constructor to initialize the state this.state. Class components should always call the base constructor with props.
State Management in Class Components
Create a stateful class component:
Counter.js file
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
export default Counter;
Render the component in src/index.js:
Example
import ReactDOM from 'react-dom';
import './index.css';
import Counter from './Counter';
const root = ReactDOM.createRoot(document.getElementById("root"));
// Render Counter component
root.render(<Counter />);
State Management in Function Components (Using Hooks)
Using React Hooks, you can use state in function components. The most commonly used Hook is useState.
Create a stateful function component:
Counter.js file
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
Render the component in src/index.js:
Example
import ReactDOM from 'react-dom';
import './index.css';
import Counter from './Counter';
const root = ReactDOM.createRoot(document.getElementById("root"));
// Render Counter component
root.render(<Counter />);
Example
Create a Clock example to understand component state:
React Example
Try it »
Next, we will make the Clock set up its own timer and update itself every second.
Adding Lifecycle Methods to the Class
In applications with many components, it is very important to release resources taken up by components when they are destroyed.
Whenever the Clock component is first loaded into the DOM, we want to set up a timer. This is called in Reactmounting。
Likewise, whenever the DOM generated by Clock is removed, we also want to clear the timer. This is called in Reactunmounting。
We can declare special methods on the component class to run some code when the component mounts or unmounts:
React Example
Try it »
Example analysis:
componentDidMount()andcomponentWillUnmount()These methods are called lifecycle hooks.
After the component output is rendered to the DOM, thecomponentDidMount()hook is executed, and we can set a timer in this hook.
this.timerID is the ID of the timer, and we cancomponentWillUnmount()clear the timer in the hook.
Code execution order:
-
When
<Clock />is passed toReactDOM.render(), React callsClockthe component's constructor. SinceClockneeds to display the current time, it initializes with an object containing the current timethis.state. We will update this state later. -
React then calls
Clockthe component'srender()method. This is how React knows what should be displayed on the screen, and then React updates the DOM to matchClockthe render output of -
When
ClockWhen the output of is inserted into the DOM, React callscomponentDidMount()the lifecycle hook. In it,Clockthe component asks the browser to set up a timer to call once every secondtick()。 -
The browser calls the
tick()method every second. In it,Clockthe component callssetState()with an object containing the current time to schedule a UI update. By callingsetState(), React knows the state has changed and callsrender()again to determine what should be displayed on the screen. This time,render()in the method,this.state.datewill be different, so the render output will contain the updated time, and the DOM is updated accordingly. -
Once the
Clockcomponent is removed from the DOM, React callscomponentWillUnmount()this hook function, and the timer will be cleared.
Data Flows From Top to Bottom
Neither parent nor child components can 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 state is often called local or encapsulated. No other components can access it except the component that owns and sets it.
In the following example, the FormattedDate component receives the date value in its props, and does not know whether it comes from Clock state, from Clock's props, or from manual input:
React Example
Try it »
This is often called top-down or one-way 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 it 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 at an arbitrary point but also flows downward.
To show that all components are truly isolated, we can create an App component that renders three Clock components:
React Example
Try it »
In the above example, each Clock component sets up its own timer and updates independently.
In React applications, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time.
We can use stateless components inside stateful components, and we can also use stateful components inside stateless components.
Other Extensions