简体   繁体   中英

React-native variable vs state

I'm trying to create a simple addition app that dynamically updates. I guess I succeeded, but I'm still trying to understand states. Why are the text s required to be a state, but result is not, even though it updates all the time?

import React from 'react';
import { StyleSheet, TextInput, StatusBar, Text, View } from 'react-native';
import Constants from 'expo';

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


  render() {
    var result = parseInt(this.state.text1) + parseInt(this.state.text2);
    return (
      <View style={styles.container}>
        <TextInput
        keyboardType="numeric"
        style={{height: 40}}
        placeholder="First"
        onChangeText={(text1) => this.setState({text1})}
        />
        <TextInput
        keyboardType="numeric"
        style={{height: 40}}
        placeholder="Second"
        onChangeText={(text2) => this.setState({text2})}
        />
        <Text>{this.state.text1&&this.state.text2 ? result : "Result will appear here."}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff'
  },
});

In the above example, your inputs are tied to the component state– whereas your result is derived from that state.

If you wanted to store "result" in state as well, technically you could, but you're setting yourself up for 1 more place that something could go wrong. See below:

import React from 'react';
import { StyleSheet, TextInput, StatusBar, Text, View } from 'react-native';
import Constants from 'expo';

export default class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {text1: null, text2: null, result: null};
  }


  render() {
    return (
      <View style={styles.container}>
        <TextInput
          keyboardType="numeric"
          style={{height: 40}}
          placeholder="First"
          onChangeText={(text1) => this.setState(state => ({
            text1,
            result: parseInt(text1) + parseInt(state.text2)
          }))}
        />
        <TextInput
          keyboardType="numeric"
          style={{height: 40}}
          placeholder="Second"
          onChangeText={(text2) => this.setState(state => ({
            text2,
            result: parseInt(text2) + parseInt(state.text1)
          }))}
        />
        <Text>{this.state.result || "Result will appear here."</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff'
  },
});

Hope that makes sense! The way you did it originally is a better way to do it!

React components are designed to refresh based on State or Prop changes. By default, and when you have not defined your own restrictions in shouldComponentUpdate , all State or Props changes will trigger a component to re-render.

To re-render means the component will execute it's render method. Whether or not the DOM is updated is handled by the virtual diff engine.

So by calling setState in response to onChangeText you are telling the component you want to make a state change. As a result a new version of state is created and the component update is triggered, calling your render method. Then it's your render method which constructs the value for result from the text changes in the new version of state.

Finally, to answer your question.

Your values for text1 and text2 are required to be part of state, in order to trigger component updates. Also, as store to persist these values between rendering.

The value for result is derived from state ie parsed, concatenation from state values. The values of result is never store anywhere, instead it is generated on demand when the component is rendered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM