We briefly went through this topic in React Native Components tutorial. Let’s dive into more details on what state is, when to use it and when not, and build some apps using state!
Table of contents
What is State?
Components in React Native use state for data that changes over time. Most of your component should not use state, but take some data from props and render it. However, sometimes you need to respond to user input.
A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props
. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way.
Real Life Analogy
You can compare component’s state with a control panel in an airplane’s cockpit. There are many various switches, dials, and knobs on that panel for a pilot to interact with a plane. That’s a stageful component which encapsulates all of the interaction logic between a pilot and an plane.
Let’s say a pilot wants to deploy landing gear before landing. They pull the landing gear control knob on the panel, which changes landing-gear-deployed
panel’s state from false
to true
, and the panel passes that changed state down to LandingGear
component as a deployed
prop. And all LandingGear
does, it’s just constantly checking deployed
prop and either deploys landing gear or pulls it back depending on true
or false
value. It doesn’t interact with a pilot directly.
You don’t want to design a plane control the way, that pilot would need to leave the cockpit and actually go to landing gear in order to deploy it. You want to keep all of the interactions with a user nice and tight within one single component above others in the hierarchy to make thing simple and minimize room for error.
What You Should Use State For
When component’s event handlers may change to trigger a UI update.
- User input. For instance, a button that triggers a change in component’s UI or an input field.
- Data that changes by timer. If you wanted to update component’s UI with timer, you would use state.
What You Should Not Use State For
Try to keep as many of your components as possible stateless. And you should never use state to store:
- Computed data. Do all of your computation within
render()
method. - Components. Build them in
render()
method based on props and state. - Duplicated data from props. You should strive to have one source of truth for your data.
How State Works
You can get, store, and update data in state. When you update state, React Native automatically re-renders component using updated state. This way your UI is always up-to-date and you don’t have to worry about updating it manually.
Defining State
To define state just add state = { key: value }
inside your component definition, where key
is the name of a piece of data you want to store, and value
is its value.
export default class App extends Component {
state = {
active: true
}
}
Getting State
To get data stored in state use this.state.key
.
export default class App extends Component {
render() {
<Text>{this.state.active}</Text>
}
}
Changing State
To change state just call this.setState({ key: newValue })
in render()
or other methods.
export default class App extends Component {
render() {
this.setState({ active: false });
}
}
Example App
Let’s build a simple example app to illustrate how state works. We’re going to have a picture on the screen which changes depending on app’s state, and a button that changes state when tapped.

Create a New Project
Open Terminal App and run following commands to create a new app project and launch it in an emulator.
react-native init LearnignStyles;
cd LearnignStyles;
react-native run-ios;
Component Boilerplate
Open index.ios.js
file and delete all of the code to start fresh. Let’s import components we’re going to need, define our component’s class, add state definition, empty render method, and empty styles outside of the class.
import React, { Component } from 'react';
import {
AppRegistry,
Image,
StyleSheet,
Text,
TouchableHighlight,
View
} from 'react-native';
export default class LearningState extends Component {
state = {
}
render() {
}
}
const styles = StyleSheet.create({
});
AppRegistry.registerComponent('LearningState', () => LearningState);
Next, let’s start filling our component boilerplate up with the code.
State
We’re going to have just one boolean value in state called happy
. Let’s set it to false
by default, so our dog is not so happy yet.
state = {
happy: false
}
Render()
Next, let’s render our image and button. We’re using this.state.happy ? true : false
condition to decide which image and button text we should use depending on current state. And we’re using TouchableHighlight
component with onPress
handler to change state.
Notice, how there is no logic to update our UI, when state is changed, present. React Native re-renders component automatically when we use
this.setState()
to change state.
render() {
return (
<View style={styles.container}>
<Image
// Change an image depending on state
source={{ uri: this.state.happy
? 'https://i.imgur.com/LNKc5V3.jpg' // happy
: 'https://i.imgur.com/74KCGU8.jpg' // not happy
}}
style={{ width: 300, height: 300 }}
/>
<TouchableHighlight
underlayColor="#4FAD54" // darker color when tapped
style={styles.buttonWrapper}
onPress={() => {
// Change state value to the opposite of current one
this.setState({ happy: !this.state.happy });
}}
>
<Text style={styles.button}>{this.state.happy
// Change a button text depending on state
? 'Take that bone away' // happy
: 'Give her a bone' // not happy
}</Text>
</TouchableHighlight>
</View>
);
}
Styles
And lastly, let’s fill up our styles.
const styles = StyleSheet.create({
container: {
flex: 1, // take all of the screen space
justifyContent: 'flex-end', // arrange children at the bottom
alignItems: 'center', // center children horizontally
},
buttonWrapper: {
backgroundColor: '#8BC051', // green background
borderRadius: 4, // round corners
margin: 60, // add margins outside button
padding: 15, // add padding inside button
},
button: {
color: '#FFFFFF', // white color
fontSize: 18, // bigger font
},
});
Result
Ok, let’s see what happens once we tap that button.


this.state.happy === false
this.state.happy === true
Challenge
Here is a little challenge for you. See, if you can change a button’s color to red when a dog is happy and post a comment with your solution.