How can I update stuff in my React Native app? Is there a way to make it change when the state changes? I can't see my updates!

I'm going to show you two ways to update your React Native app.

You're definitely going to want to update the frontend of your app. That's what makes it interactive, and feel like... well, an app.

Maybe you've tried using state in React, but for some reason you're having problems and your app just doesn't update.

This might be a little confusing at first, especially if you're used to just setting a variable and having the UI magically update. It can feel like React doesn't want to allow you to make updates, but in order to be smart about how and when to actually refresh the screen, React makes us do a little more work.

Let's have a look at how we can update our UI in React Native with the setState() function.

Updating text

Have a look at the following React component, <Hello/>. There are a few things going on here:

  • In the constructor we set some initial state by assigning an object to this.state. The property this.state in a React class must be an object.
  • We're displaying the value of this.state.name in the render() method.
  • There's a <TextInput> component that is triggering changes on its onChangeText property. We're sending the updated text to a class method this.updateName which will get a text argument from onChangeText.
  • In this.updateName(), we're using setState() to update our this.state.name to the text value or, if it's empty, a default value.
import React from 'react';
import { Text, TextInput, View } from 'react-native';

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: 'World' };
  }

  render() {
    return (
      <View>
        <Text>Hello {this.state.name}!</Text>
        <TextInput
          placeholder="What's your name?"
          onChangeText={this.updateName}
        />
      </View>
    );
  }

  updateName = text => {
    if (text) {
      this.setState({ name: text });
    } else {
      this.setState({ name: 'World' });
    }
  };
}

Toggling things on and off

Let's look at a slightly different example in the <Awake/> component. A lot of things are the same, but there's a difference in how we're using the setState() function.

  • We're still setting initial values in the constructor.
  • We're using this.state.isAwake to display either an awake or sleeping emoji.
  • We're using this.state.isAwake to set the value of the <Switch/>, which will cause the switch UI to update.
  • The <Switch/> property of onValueChange triggers this.toggleSleep. _Notice that onValueChange won't pass a value to this.toggleSleep.
  • This time around we're passing a function into this.setState() instead of an object. This function receives the state as the first argument, and must return an object with the updated state.

The benefit of using this.setState() with a function argument is that React will make sure that the state argument is never outdated. That'll save you from accidentally updating your state based on an old value.

In other words you'll never find yourself in the mysterious situation of switching from awake... to awake.

import React from 'react';
import { Text, Switch, View } from 'react-native';

class Awake extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isAwake: true };
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.bigEmoji}>
          {this.state.isAwake && '😃'}
          {!this.state.isAwake && '😴'}
        </Text>
        <View style={styles.toggleContainer}>
          <Switch
            value={this.state.isAwake}
            onValueChange={this.toggleSleep}
          /><Text>Awake</Text>
        </View>
      </View>
    );
  }

  toggleSleep = () => {
    this.setState(state => {
      return { isAwake: !state.isAwake };
    });
  };
}

Runnable Example

Open this Snack to see everything put into action.