简体   繁体   中英

this.setState not changing state when using onChangeText React Native

I've tried a few methods to get setState() to update the value of state. Currently the text in the <TextInput> changes, but the value in this.state doesn't change.

I have the console.log in the right place, I've tried writing external functions, I've messed around with the variable's names but nothing seems to work.

import * as React from 'react';
import { View, Text, TextInput, TouchableHighlight, Dimensions, StyleSheet } from "react-native";

import PropTypes from "prop-types";

class EditNote extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      title: '',
      text: '',
      id: ''
    }
  }

  // TODO: Change textboxes to match the props from the NoteList
  static getDerivedStateFromProps(props){
    return(
      {...props.route.params}
    )
  }

  render(){
    return(
      <View style={s.container}>
        <View style={s.titleContainer}>
          <Text style={s.titleText}>Edit Note</Text>
          <View style={{flex: 1}}/>
        </View>
        <View style={s.inputContainer}>
          <TextInput
            style={{...s.input, ...s.titleInput}}
            autoCapitalize='words'
            keyboardAppearance='dark'
            placeholderTextColor='#DDD'
            onChangeText={(title) => { this.setState({title: title}, () => console.log(this.state)) }}
            defaultValue={this.state.title}
          />
          <TextInput
            style={{...s.input, ...s.textInput}}
            autoCapitalize='sentences'
            keyboardAppearance='dark'
            placeholderTextColor='#DDD'
            multiline
            onChangeText={(text) => { this.setState({text: text}, () => console.log(this.state)) }}
            defaultValue={this.state.text}
          />
        </View>
        
        <View style={s.buttonContainer}>
          <TouchableHighlight
            style={s.backButton}
            onPress={() => this.props.nav.navigate('NoteListView')}
            underlayColor='#300030'
          >
            <Text style={s.buttonText}>Cancel</Text>
          </TouchableHighlight>
          <TouchableHighlight
            style={s.addButton}
            onPress={() => {
              console.log(this.state.note)
              this.props.nav.navigate('NoteListView', {note: this.state, mode: 'edit'})
            }}
            underlayColor='#300030'
          >
            <Text style={s.buttonText}>Edit</Text>
          </TouchableHighlight>
        </View>
      </View>
    )
  }
}

export default EditNote

I just realized that this is a problem with two parts.

The first problem is that props.route.params is unaffected by subsequent render() calls. This means that even if you re-render the component, the same initial properties are used.

The second is getDerivedStateFromProps() . Every time the render function is called it calls getDerivedStateFromProps() right before it which sets the state to the initial route parameters.

This problem can be fixed by:

  1. Clearing the initial route parameters in the render function after their initial use. Something a little like this at the beginning of the render() function will work. this.props.route.params = undefined
  2. Using an if statement and a variable in state to regulate when the props should update the state.
  3. Refactor the code to make use of the props

Option 3 is how things should be correctly done but the best solution depends on how your code works.

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