this.setState未定义

时间:2016-08-29 16:31:40

标签: reactjs react-native

我一直在看到使用的答案=>或.bind(this)但这些解决方案都没有起作用。

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

export default class MyWeatherApp extends Component {
  constructor(props) {
  super(props);

  this.state = {};
}

getInitialState() {
  return {
    zip: '',
    forecast: null,
  };
}

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

解决方案:

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

8 个答案:

答案 0 :(得分:47)

使用ES2015类语法var sec=second.replace("[^\\d.]", ""); tss.getRange(counter2, 5).setValue(sec); extend时,您需要将操作处理程序绑定到类的上下文。

试试这个:React.Component

通常,最好不要在onChange={e => _handleTextChange(e)}内使用箭头函数或bind方法,因为它会在任何render调用上生成函数的新副本。将函数声明移动到render

我个人更喜欢在这种情况下使用箭头函数作为类属性

class constructor

它不是ES2015规范的一部分,但babel stage-0 preset支持此语法

您可以在this article

中的React中阅读有关上下文绑定的更多信息

答案 1 :(得分:12)

让我详细说一下。因为我不得不浪费大量时间研究它和我不想让任何人重复这个......

如果你不使用箭头功能,你必须绑定this,如Line' 9'

class MyClass extends React.Component {

  handleButtonClick(){
    console.log("Hello from here");
  };

  render() {
    return (
      <button onClick={this.handleButtonClick.bind(this)}>Click me</button>
    );
  }
}

另一种方法是使用ES6 Arrow功能。你不需要绑定这个&#39;在这种情况下。安装&#bab; stage1预设&#39;会支持这个。

在项目中运行以下命令:

npm i babel-preset-stage-1 --save

你的.babelrc看起来像这样。特别是&#39; stage-1&#39;在预设中。

{
  "presets": ["es2015", "react", "stage-1"],
  "env": {
    "development": {
      "plugins": ["react-hot-loader/babel"]
    }
  }
}

你的组件就像这样,正如我所说:

class MyClass extends React.Component {

      handleButtonClick = () => {
        console.log("Hello from here");
      };

      render() {
        return (
          <button onClick={this.handleButtonClick}>Click me</button>
        );
      }
    }

答案 2 :(得分:3)

问题是:我有 ERROR :this.setState不是函数

鉴于我将我的函数绑定到组件构造函数中的状态,如下所示:

public class SearchHistoryViewModel : MvxViewModel
{

  //properties
  ...
  ...
    private readonly MvxSubscriptionToken _token; 


    //ctor
    public SearchHistoryViewModel(ISearchHistoryService searchHistoryService, IMvxNavigationService navigationService, IMvxMessenger messenger)
    {
        _searchHistoryService = searchHistoryService;
        _navigationService = navigationService;

  /*Subscribe - Whenever a SearchFilterMessage is received, trigger the 
  OnFilterMessage method */
        _token = messenger.Subscribe<SearchFilterMessage>((message => { 
  OnFilterMessage(message.FilterName); })
            );
    }

    //methods
  ....
  ....
  ....
    /* Do this Whenever the SearchFilterMessage is received*/
   public async void OnFilterMessage(string name)
    {
        HistoryItems = await _searchHistoryService.GetHistoryByName(name);
    }

我的职责是:

 this.getRequestData = this.getRequestData.bind(this);

解决方案是使用getRequestData(){ axios.post('http://example.com/getInfo', jsonData) .then(function (res) { console.log(res); }) .catch(function (error) { console.log(error); }); this.setState({ stateVaribale }); }) } 而不是在axios请求中使用arrow functions函数,因为引起参与axios请求中的函数的反应令人困惑而不是组件状态

keyword

答案 3 :(得分:1)

您需要绑定操作,否则您将在浏览器中看到未定义的错误 有三种方法可以约束您的动作

  1. 将处理程序绑定到render方法中 this.chngHandler.bind(this)

例如-

export class EventBind extends Component{
constructor(){
    super()
    this.state = {
        msg:'hello'
    }
}
chngHandler(){
    this.setState({
         msg:'Good bye'
    })
}
render(){
    return(
        <div>
            {this.state}
            <button onClick={this.chngHandler.bind(this)}>click</button>
        </div>
    )
 } }
    渲染()=>this.EventHandler()中的
  1. 箭头函数方法

例如-

export class EventBind extends Component{
constructor(){
    super()
    this.state = {
        msg:'hello'
    }
}
chngHandler(){
    this.setState({
         msg:'Good bye'
    })
}
render(){
    return(
        <div>
            {this.state}
            <button onClick={()=>this.chngHandler()}>click</button>
        </div>
    )
}}`

3。在构造函数中绑定事件处理程序 this.EventHandler = this.EventHandler.bind(this) 例如-

export class EventBind extends Component{
constructor(){
    super()
    this.state = {
        msg:'hello'
    }
    this.chngHandler = this.chngHandler.bind(this)
}
chngHandler(){
    this.setState({
         msg:'Good bye'
    })
}
render(){
    return(
        <div>
            {this.state}
            <button onClick={this.chngHandler}>click me </button>
        </div>
    )
}}

因为绑定在构造函数中发生一次,所以比render方法中的绑定要好

第三种方法也可以这样-:

export class EventBind extends Component{
constructor(){
    super()
    this.state = {
        msg:'hello'
    }
    this.chngHandler = this.chngHandler.bind(this)
}
// chngHandler(){
//     this.setState({
//          msg:'Good bye'
//     })
// }
chngHandler = ()=>{
    this.setState({
        msg:'Good Bye'
    })
}
render(){
    return(
        <div>
            {this.state}
            <button onClick={this.chngHandler}>click me </button>
        </div>
    )
}}

答案 4 :(得分:0)

你也可以在constructor像这样绑定

class MyClass extends React.Component {
  constructor(props){
    super(props);
    this.handleButtonClick = this.handleButtonClick.bind(this);
 }
  handleButtonClick(){
    console.log("Hello from here");
  }

  render() {
    return (
      <button onClick={this.handleButtonClick}>Click me</button>
    );
  }
}

答案 5 :(得分:0)

当您在调用另一个函数的方法中使用粗箭头函数时,

也可以用于本机响应。 例如 .then((response) => { this.setState({....}) }

答案 6 :(得分:0)

每当在axios请求之类的api调用中使用此方法时,在某些情况下,“ this”上下文仍然是不确定的。 在这里只详细说明其中的一个:

`

import react from 'React'
class Test extends from React.Component {
constructor() {
super();
this.state = {
data: '',
error: ''
}
}
componentDidMount() {
url = 'http://abc.go.com';
axios.get(url).then(function(resposne) {   // Everything fine till now
this.setState({ data: response });   //Oops this context is undefined
}
).catch(function(err) {
 this.setState({ error: err });       // again this context remains to be undefined
});
}
render() {
return ( <div>this.state.data</div> ) 
}
}`

当您运行上面的代码时,您肯定会得到类似类型的错误 未定义的setState被调用,与此类似。

您该如何解决? 您可以遵循两种方法来解决这种特殊类型的问题:

第一个是您可以在将要调用api的函数中定义一个变量,并为其分配'this'值,然后您可以从该变量中引用状态对象。

import react from 'React'
class Test extends React.Component
{
  constructor() { 
     super();
     this.state = {
       data: '',
       error: ''
  };
  componentDidMount() {
   let url = 'http://abc.go.com';
   currentContext = this;   // variable to be assigned this context
   axios.get(url).then(function(resposne) {   // Everything fine till now
   currentContext.setState({ data: response });   //Oops this context is undefined
   }
   ).catch(function(err) {
  currentContext.setState({ error: err });       // again this context remains to be undefined
 });
  }
 render() {
  return ( <div>this.state.data</div> ) 
 }
 }

您可以使用的第二种方法是通过在axios中定义箭头功能,如下所示

axios.get(url).then((response) => {
  this.setState({ data: response })     //will always be bound to the this context
}) 

答案 7 :(得分:0)

在react native中,使用axios作为示例时会出现此错误

    componentDidMount(){
    axios.get('https://the request url')
    .then( function(response) {
      this.setState({products:response.data.products});
    })
    .catch(function(error) {
      console.log(error);
    })
}

如果我们这样尝试,就会得到:

未定义不是对象(正在评估'this.setState')

那么我们该如何解决呢,我们可以使用这样的箭头功能来解决

componentDidMount(){
        axios.get('https://the request url')
        .then( (response)=> {
          this.setState({products:response.data.products});
        })
        .catch((error)=> {
          console.log(error);
        })
    }

这将解决问题,希望对您有帮助