React Native:this.setState不是函数

时间:2016-07-18 15:44:19

标签: javascript reactjs react-native

我在这里看到了很多关于同一问题的问题,但它似乎与我遇到的问题无关,而且有点复杂。

我正在学习ReactJS和React Native。我正在阅读并遵循“学习反应原生”一书中的代码示例:https://github.com/bonniee/learning-react-native

由于某种原因,当调用handleTextChange函数时,在下面的代码中调用this.setState会导致“this.SetState不是函数”。错误。我的问题是为什么?与关于同一问题的其他问题不同,我不相信我对this.stateState的调用隐藏在回调函数或if语句中。为什么不明确?

这是我的代码:

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: "",
      forecast: null
    };
  }

  _handleTextChange(event) {
    this.setState({zip: event.nativeEvent.text});
  }

    render() {
    return (
      <View style={styles.container}>
      <Text style={styles.welcome}>
      You input {this.state.zip}.
      </Text>
      <TextInput
      style={styles.input}
      onSubmitEditing={this._handleTextChange}/>
      </View>
    );
  }
}

5 个答案:

答案 0 :(得分:42)

不要在渲染中使用bind。 bind是一个相当昂贵的操作,应该只发生一次。你有两个选择:

在构造函数中绑定函数:

this._handleTextChange = this._handleTextChange.bind(this);

或使用箭头功能:

onSubmitEditing={(e) => this._handleTextChange(e)} />

修改

显然,渲染中的箭头函数也是一种不好的做法(在下面的评论和答案中向Adam Terlson致谢)。您可以阅读eslint docs,其中说明:

  

JSX prop中的绑定调用或箭头函数将在每个渲染上创建一个全新的函数。这对性能不利,因为它会导致垃圾收集器的调用方式超出必要的范围。

使用箭头函数显然没有使用bind那么糟糕,但应该避免使用。

答案 1 :(得分:10)

关于箭头功能,您还需要更改_handleTextChange(event)函数。其他答案没有讨论如何将普通功能更改为箭头功能。因此,提供可能有助于他人的答案

您需要更改处理程序功能

来自

_handleTextChange(event) {
    this.setState({zip: event.nativeEvent.text});
  }

收件人

_handleTextChange = event => {
   this.setState({zip: event.nativeEvent.text});
 }

答案 2 :(得分:7)

问题是上下文绑定,正如其他评论和答案中所述。

但是,绑定本身的性能不是问题。方法更相关的问题是在渲染方法中使用bind 或箭头会在每个渲染上创建一个新函数,从而导致接收它们的子项更改道具,从而强制重新渲染

您有两个可行的选择:

class WeatherProject extends Component {
  constructor(props) {
    super(props);

    this._handleTextChange = this._handleTextChange.bind(this);
  }
  // ...
}

或者,如果您使用babel plugin,则可以使用类属性表示法并指定箭头函数。

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    // ...
  }

  handleTextChange = (event) => {
    this.setState({zip: event.nativeEvent.text});
  }
  // ...
}

我强烈建议您使用启用了react recommended rules的eslint包。它将捕获错误,例如在渲染中使用bind /箭头,以及告诉您下划线前缀函数是丑陋的,并且在React中完全没有必要。 :)

答案 3 :(得分:1)

this.setState不是函数---使用this

解决
 let that = this;

 that.setState({membersArray:response.data})

答案 4 :(得分:1)

尝试设置状态时,我遇到了同样的问题。当我将函数绑定到构造函数中时,问题就解决了。检查以下绑定

 constructor(props) {
    super(props);
    this.state = {
      zip: "",
      forecast: null
    };

   this._handleTextChange = this._handleTextChange.bind(this);

  }