简体   繁体   English

this.setState 未定义

[英]this.setState is undefined

I keep seeing answers that say to use => or .bind(this) but neither of those solutions worked.我一直看到答案说使用 => 或 .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});
}

Solution:解决方法:

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

When you extend React.Component with ES2015 class syntax you need to bind your action handlers to a context of your class.当您使用 ES2015 类语法extend React.Component ,您需要将操作处理程序绑定到类的上下文。

Try this: onChange={e => _handleTextChange(e)}试试这个: onChange={e => _handleTextChange(e)}

Generally, it's better not to use arrow functions or bind methods inside render as it generates a new copy of the function on any render call.通常,最好不要在render使用箭头函数或bind方法,因为它会在任何render调用中生成函数的新副本。 Move function declaration to the class constructor .将函数声明移至class constructor

I personally prefer to use arrow functions as class properties in this case在这种情况下,我个人更喜欢使用箭头函数作为类属性

class MyClass extends React.Component {

  handleClick = () => {
    // your logic
  };

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

It's not a part of ES2015 specification but babel stage-0 preset supports this syntax它不是 ES2015 规范的一部分,但babel stage-0 预设支持这种语法

You can read more about context binding in React in this article您可以在本文中阅读有关 React 中上下文绑定的更多信息

Let me write this in detail.让我详细写一下。 As I had to waste a lot of time in researching it & I don't want anyone to repeat this...因为我不得不浪费很多时间来研究它&我不希望任何人重复这个......

If you dont use Arrow Function you have to bind this like Line '9'如果你不使用箭头函数,你必须像 Line '9' 一样绑定this

class MyClass extends React.Component {

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

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

Another way is using ES6 Arrow function.另一种方法是使用 ES6 箭头函数。 You need not bind 'this' in this case.在这种情况下,您不需要绑定“this”。 Installing 'babel stage-1 preset' will support this.安装 'babel stage-1 preset' 将支持这一点。

Run the command below in your project:在您的项目中运行以下命令:

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

Your .babelrc will look like this.你的 .babelrc 看起来像这样。 Specially 'stage-1' in the preset.特别是预设中的“stage-1”。

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

Your component will be like this, as I said:正如我所说,您的组件将是这样的:

class MyClass extends React.Component {

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

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

The problem was: I had that ERROR : this.setState is not a function问题是:我有那个错误:this.setState is not a function

Given i was binding my function to the state in component constructor, like this:鉴于我将我的函数绑定到组件构造函数中的状态,如下所示:

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

and my function was:我的功能是:

getRequestData(){
    axios.post('http://example.com/getInfo', jsonData)
                        .then(function (res) {
                            console.log(res);
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
                        this.setState({ stateVaribale });
                    })
}

the solution is to use arrow functions instead of using keyword function in the axios request, cause it's confusing to react to refer to the function in axios request instead of the component state .解决方案是在 axios 请求中使用arrow functions而不是使用keyword function,导致在 axios 请求中引用函数而不是组件 state会造成混淆。

getRequestData(){
axios.post('http://example.com/getInfo', jsonData)
                        .then(res => {
                        console.log(res);
                        })
                        .catch(error => {
                            console.log(error);
                        });
                        this.setState({ stateVaribale });
                    })}

also you can bind this in constructor like this你也可以像这样在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>
    );
  }
}

in react native, we got this error when we use axios, as an example在 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);
    })
}

if we try like this we got :如果我们这样尝试,我们会得到:

undefined is not an object (evaluating 'this.setState') undefined 不是一个对象(评估'this.setState')

so how we can fix this, we can fix it using arrow function like this那么我们如何解决这个问题,我们可以使用这样的箭头函数来解决它

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

this will solve the problem, hope this will helpful这将解决问题,希望这会有所帮助

you need to bind your action otherwise you can see error called undefined in your browser there are three methods for binding your action您需要绑定您的操作,否则您会在浏览器中看到名为 undefined 的错误 有三种方法可以绑定您的操作

  1. bind the handler in the render method this.chngHandler.bind(this)在渲染方法 this.chngHandler.bind(this) 中绑定处理程序

for eg-例如-

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>
    )
 } }
  1. arrow function approach in render ()=>this.EventHandler() render ()=>this.EventHandler()箭头函数方法

for example-例如——

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.Binding the event handler in the constructor this.EventHandler = this.EventHandler.bind(this) for example-: 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>
    )
}}

because the binding happens once in the constructor this is better than a binding in the render method因为绑定在构造函数中发生一次,这比渲染方法中的绑定更好

3rd approach can also be done like this -:第三种方法也可以这样做 - :

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>
    )
}}

works for react-native too when you use fat arrow functions inside the methods you are invoking another function.当您在调用另一个函数的方法中使用粗箭头函数时,也适用于 react-native。 eg .then((response) => { this.setState({....}) }例如.then((response) => { this.setState({....}) }

Whenever you are using this inside an api call like axios request There are cases where your 'this' context remains to be undefined.每当您在像 axios 请求这样的 api 调用中使用 this 时,在某些情况下,您的“this”上下文仍未定义。 Elaborating few of them here-:在这里详细说明其中的一些-:

` `

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> ) 
}
}`

when you will run the above code you will definitely get a type error like setState of undefined is being called, Something similar to this.当你运行上面的代码时,你肯定会得到一个类型错误,比如 setState of undefined 被调用,类似的东西。

How can you solve this?你怎么能解决这个问题? There are two methods that you can follow to solve this particular type of question-:您可以采用两种方法来解决这种特定类型的问题:

First one is you can define a variable inside the function where you'll be calling the api and assign it the value of 'this' and from that variable you can reference your state object.第一个是您可以在函数内定义一个变量,您将在其中调用 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> ) 
 }
 }

Second method that you can use is by defining arrow function in axios like given below您可以使用的第二种方法是在 axios 中定义箭头函数,如下所示

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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