this.setState 未定义

IT技术 reactjs react-native
2021-04-14 09:11:58

我一直看到答案说使用 => 或 .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');
}
6个回答

当您extend React.Component使用 ES2015 类语法时,您需要将操作处理程序绑定到类的上下文。

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

通常,最好不要在bind内部使用箭头函数或方法,render因为它会在任何render调用时生成函数的新副本将函数声明移至class constructor.

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

class MyClass extends React.Component {

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

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

它不是 ES2015 规范的一部分,但babel stage-0 预设支持这种语法

您可以在本文中阅读有关 React 中上下文绑定的更多信息

不,按钮只是一个 html 元素。检查您的 jsx 转译器是否正常工作。哦,我明白了。如果您使用 React Native,则应该TouchableElement改为
2021-05-27 09:11:58
我无法导入按钮组件。我需要通过 NPM 安装它吗?
2021-05-30 09:11:58
@EmanuelQuimper 如果子组件是纯的,它很可能会对其 props 进行浅层相等检查,以查看它们中的任何一个是否不同,以避免在没有更改的情况下重新渲染。如果你在你的渲染中创建你的 Lamba 方法,你onChange每次渲染时都会创建一个新的,子组件将看到这个“新”属性并在不需要时重新渲染。
2021-06-04 09:11:58
“通常,最好不要在渲染中使用箭头函数或绑定方法,因为它会在任何渲染调用中生成函数的新副本。将函数声明移至类构造函数。” 你在这里是什么意思?所以我的方式onChange={e => _handleTextChange(e)}是不是最好的方式?
2021-06-12 09:11:58
@Brandon 感谢您的解释。
2021-06-17 09:11:58

让我详细写一下。因为我不得不浪费很多时间来研究它&我不希望任何人重复这个......

如果你不使用箭头函数,你必须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 箭头函数。在这种情况下,您不需要绑定“this”。安装 'babel stage-1 preset' 将支持这一点。

在您的项目中运行以下命令:

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

你的 .babelrc 看起来像这样。特别是预设中的“stage-1”。

{
  "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>
        );
      }
    }
babel 预设 2 或 3 支持这个吗?我觉得使用 stage-1 预设并不安全,因为新功能仍处于早期阶段。
2021-05-22 09:11:58

问题是:我有那个错误:this.setState is not a function

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

 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而不是使用keyword函数,导致在 axios 请求中引用函数而不是组件 state会造成混淆

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

你也可以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>
    );
  }
}

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

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

undefined 不是一个对象(评估'this.setState')

那么我们如何解决这个问题,我们可以使用这样的箭头函数来解决它

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

这将解决问题,希望这会有所帮助