this.setState is undefined

前端 未结 8 2077
无人及你
无人及你 2020-12-09 01:24

I keep seeing answers that say to use => or .bind(this) but neither of those solutions worked.

import React, { Component } from \'react\';
import { View, Tex         


        
相关标签:
8条回答
  • 2020-12-09 01:59

    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'

    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. You need not bind 'this' in this case. Installing 'babel stage-1 preset' will support this.

    Run the command below in your project:

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

    Your .babelrc will look like this. Specially 'stage-1' in the preset.

    {
      "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>
            );
          }
        }
    
    0 讨论(0)
  • 2020-12-09 01:59

    Whenever you are using this inside an api call like axios request There are cases where your 'this' context remains to be undefined. 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.

    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.

    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.get(url).then((response) => {
      this.setState({ data: response })     //will always be bound to the this context
    }) 
    
    0 讨论(0)
  • 2020-12-09 02:08

    also you can bind this in constructor like this

    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>
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-09 02:09

    When you extend React.Component with ES2015 class syntax you need to bind your action handlers to a context of your class.

    Try this: 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. Move function declaration to the 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

    You can read more about context binding in React in this article

    0 讨论(0)
  • 2020-12-09 02:10

    The problem was: I had that ERROR: 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 keywordfunction in the axios request, cause it's confusing to react to refer to the function in axios request instead of the component state.

    getRequestData(){
    axios.post('http://example.com/getInfo', jsonData)
                            .then(res => {
                            console.log(res);
                            })
                            .catch(error => {
                                console.log(error);
                            });
                            this.setState({ stateVaribale });
                        })}
    
    0 讨论(0)
  • 2020-12-09 02:10

    in react native, we got this error when we use axios, as an example

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

    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

    0 讨论(0)
提交回复
热议问题