I have a very simple React Native sample here. I am very new to React Native (and also to React).

I have a state with a variable text1.

It is logged to console with button "log data".

It is set to the current timestring with button "change data".

And if an input is done then it will get that data.

The content of text1 is shown in a Text-Element.

import React from 'react';
import { StyleSheet, Text, View, Button, Alert,TextInput} from 'react-native';


export default class App extends React.Component 
{
    constructor(props) 
    {
        super(props);
        this.state = {text1: 'initial'};
    }

    setVal () 
    {
        this.setState (st => {st.text1 = new Date ().toString ()});
        //this.forceUpdate ();
    }

    render()
    {
        return (
            <View style={{ alignItems: 'center', justifyContent: 'center', flex: 1}}>
            <Text style={{fontSize: 30, margin: 40}}>text1 is {this.state.text1}</Text>


            <Button
                onPress={
                            () => {console.log("text1=" + this.state.text1);
                        }}
                title="log data"
                color="green"
            />

            <Button
                onPress={this.setVal.bind (this)}
                title="change data"
                color="orange"
            />


           <TextInput
                style={{height: 40, width: 200, margin: 30, borderColor: 'grey', borderWidth: 2}}
                onChangeText={str => this.setState({text1: str})}
                value={this.state.text1}
            />
      </View>
    );
  }
}

If I change text1 by doing an input then the Text-Element is updated immediately. That is not the case if I do it by button "change data" and not call foreceUpdate.

I thought setState would automatically perform update and render. ???

Why is that

1 Answers

1
wvteijlingen On Best Solutions

setState requires you to return a new object that will be merged into the current state. According to the docs:

[The state argument] should not be directly mutated. Instead, changes should be represented by building a new object based on the input from state and props. (...) The output of the updater is shallowly merged with state.

So you should not mutate the st argument, but instead just return an object:

this.setState({ text1: new Date().toString() });