These docs are old and won’t be updated. Go toreact.dev for the new React docs.
These new documentation pages teach modern React and include live examples:
This page introduces the concept of state and lifecycle in a React component. You can find adetailed component API reference here.
Consider the ticking clock example fromone of the previous sections. InRendering Elements, we have only learned one way to update the UI. We callroot.render() to change the rendered output:
const root= ReactDOM.createRoot(document.getElementById('root'));functiontick(){const element=(<div><h1>Hello, world!</h1><h2>It is{newDate().toLocaleTimeString()}.</h2></div>); root.render(element);}setInterval(tick,1000);In this section, we will learn how to make theClock 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'));functionClock(props){return(<div><h1>Hello, world!</h1><h2>It is{props.date.toLocaleTimeString()}.</h2></div>);}functiontick(){ root.render(<Clockdate={newDate()}/>);}setInterval(tick,1000);However, it misses a crucial requirement: the fact that theClock sets up a timer and updates the UI every second should be an implementation detail of theClock.
Ideally we want to write this once and have theClock update itself:
root.render(<Clock/>);To implement this, we need to add “state” to theClock component.
State is similar to props, but it is private and fully controlled by the component.
You can convert a function component likeClock to a class in five steps:
React.Component.render().render() method.props withthis.props in therender() body.classClockextendsReact.Component{render(){return(<div><h1>Hello, world!</h1><h2>It is{this.props.date.toLocaleTimeString()}.</h2></div>);}}Clock is now defined as a class rather than a function.
Therender method will be called each time an update happens, but as long as we render<Clock /> into the same DOM node, only a single instance of theClock class will be used. This lets us use additional features such as local state and lifecycle methods.
We will move thedate from props to state in three steps:
this.props.date withthis.state.date in therender() method:classClockextendsReact.Component{render(){return(<div><h1>Hello, world!</h1><h2>It is{this.state.date.toLocaleTimeString()}.</h2></div>);}}this.state:classClockextendsReact.Component{constructor(props){super(props);this.state={date:newDate()};}render(){return(<div><h1>Hello, world!</h1><h2>It is{this.state.date.toLocaleTimeString()}.</h2></div>);}}Note how we passprops to the base constructor:
constructor(props){super(props);this.state={date:newDate()};}Class components should always call the base constructor withprops.
date prop from the<Clock /> element:root.render(<Clock/>);We will later add the timer code back to the component itself.
The result looks like this:
classClockextendsReact.Component{constructor(props){super(props);this.state={date:newDate()};}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/>);Next, we’ll make theClock set up its own timer and update itself every second.
In applications with many components, it’s very important to free up resources taken by the components when they are destroyed.
We want toset up a timer whenever theClock is rendered to the DOM for the first time. This is called “mounting” in React.
We also want toclear that timer whenever the DOM produced by theClock 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:
classClockextendsReact.Component{constructor(props){super(props);this.state={date:newDate()};}componentDidMount(){}componentWillUnmount(){}render(){return(<div><h1>Hello, world!</h1><h2>It is{this.state.date.toLocaleTimeString()}.</h2></div>);}}These methods are called “lifecycle methods”.
ThecomponentDidMount() 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 onthis (this.timerID).
Whilethis.props is set up by React itself andthis.state 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 thecomponentWillUnmount() lifecycle method:
componentWillUnmount(){clearInterval(this.timerID);}Finally, we will implement a method calledtick() that theClock component will run every second.
It will usethis.setState() to schedule updates to the component local state:
classClockextendsReact.Component{constructor(props){super(props);this.state={date:newDate()};}componentDidMount(){this.timerID=setInterval(()=>this.tick(),1000);}componentWillUnmount(){clearInterval(this.timerID);}tick(){this.setState({date:newDate()});}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/>);Now the clock ticks every second.
Let’s quickly recap what’s going on and the order in which the methods are called:
<Clock /> is passed toroot.render(), React calls the constructor of theClock component. SinceClock needs to display the current time, it initializesthis.state with an object including the current time. We will later update this state.Clock component’srender() method. This is how React learns what should be displayed on the screen. React then updates the DOM to match theClock’s render output.Clock output is inserted in the DOM, React calls thecomponentDidMount() lifecycle method. Inside it, theClock component asks the browser to set up a timer to call the component’stick() method once a second.tick() method. Inside it, theClock component schedules a UI update by callingsetState() with an object containing the current time. Thanks to thesetState() call, React knows the state has changed, and calls therender() method again to learn what should be on the screen. This time,this.state.date in therender() method will be different, and so the render output will include the updated time. React updates the DOM accordingly.Clock component is ever removed from the DOM, React calls thecomponentWillUnmount() lifecycle method so the timer is stopped.There are three things you should know aboutsetState().
For example, this will not re-render a component:
// Wrongthis.state.comment='Hello';Instead, usesetState():
// Correctthis.setState({comment:'Hello'});The only place where you can assignthis.state is the constructor.
React may batch multiplesetState() calls into a single update for performance.
Becausethis.props andthis.state 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:
// Wrongthis.setState({counter:this.state.counter+this.props.increment,});To fix it, use a second form ofsetState() 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:
// Correctthis.setState((state, props)=>({counter: state.counter+ props.increment}));We used anarrow function above, but it also works with regular functions:
// Correctthis.setState(function(state, props){return{counter: state.counter+ props.increment};});When you callsetState(), React merges the object you provide into the current state.
For example, your state may contain several independent variables:
constructor(props){super(props);this.state={posts:[],comments:[]};}Then you can update them independently with separatesetState() calls:
componentDidMount(){fetchPosts().then(response=>{this.setState({posts: response.posts});});fetchComments().then(response=>{this.setState({comments: response.comments});});}The merging is shallow, sothis.setState({comments}) leavesthis.state.posts intact, but completely replacesthis.state.comments.
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:
<FormattedDatedate={this.state.date}/>TheFormattedDate component would receive thedate in its props and wouldn’t know whether it came from theClock’s state, from theClock’s props, or was typed by hand:
functionFormattedDate(props){return<h2>It is{props.date.toLocaleTimeString()}.</h2>;}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 anApp component that renders three<Clock>s:
functionApp(){return(<div><Clock/><Clock/><Clock/></div>);}EachClock 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.