【问题标题】:how do I use "this" on an component function in react?如何在组件功能上使用“this”进行反应?
【发布时间】:2022-01-14 20:53:52
【问题描述】:

我需要从Animal 组件调用this.getFact,但使用this 会引发TypeError: this is undefined

import './App.css';
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fact: '',
    }
  }

  getFact(endpoint) {
    fetch(endpoint)
      .then(response => response.json())
      .then(data => {
        this.setState({
          fact: data.text,
        });
      })
  }

  Animal(props) {
    return (
      <div>
        <h1>{props.name}</h1>
        <button onClick={() => this.getFact(props.endpoint)}>get a {props.name.toLowerCase()} fact</button>
      </div>
    )
  }

  render() {
    return (
      <div className="App">
        <div>
          <p>{this.state.fact}</p>
        </div>
        <div className="animals">
          <this.Animal name="Dog" endpoint="https://some-random-api.ml/facts/dog" />
          <this.Animal name="Cat" endpoint="https://some-random-api.ml/facts/dog" />
          <this.Animal name="Bird" endpoint="https://some-random-api.ml/facts/dog" />
          <this.Animal name="Otter" endpoint="https://some-random-api.ml/facts/dog" />
        </div>
      </div>
    );
  }
}

export default App;

【问题讨论】:

  • 您没有Animal 组件。您的 App 组件上有一个 Animal 方法。使用自己的方法创建一个新组件(或使用钩子创建一个新的功能组件)。

标签: javascript reactjs


【解决方案1】:

您需要绑定两个函数(getFact 和 Animal)才能在 Animal 函数中使用 this。在你的构造函数中这样做:

  constructor(props) {
    super(props);
    this.state = {
      fact: ""
    };

    // Here you will bind the functions so they can be callable with this
    this.getFact = this.getFact.bind(this);
    this.Animal = this.Animal.bind(this);
  }

这将解决问题,但我建议将 Animal 组件移到您的班级之外,并将 getFact 作为道具传递。您仍然需要绑定 getFact 函数,但老实说,它会更像反应,并且从长远来看更易于维护。像这样的

function Animal(props) {
  return (
    <div>
      <h1>{props.name}</h1>
      <button onClick={() => props.getFact(props.endpoint)}>
        get a {props.name.toLowerCase()} fact
      </button>
    </div>
  );
}

class AppReactWay extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fact: ""
    };
    this.getFact = this.getFact.bind(this);
  }

// Same code as you have

  render() {
    return (
      <div className="App">
        <div>
          <p>{this.state.fact}</p>
        </div>
        <div className="animals">
          <Animal
            name="Dog"
            getFact={this.getFact}
            endpoint="https://some-random-api.ml/facts/dog"
          />
        </div>
      </div>
    );
  }
}

export default App;

同样检查API响应后需要修改getFact函数,不是data.text,是data.fact。

  getFact(endpoint) {
    fetch(endpoint)
      .then((response) => response.json())
      .then(({ fact }) => {
        this.setState({
          fact
        });
      });
  }

这是一个有效的sandbox,包含两个示例。

【讨论】:

    【解决方案2】:

    更好的方法是为每只动物直接调用{this.Animal({ name: 'Dog', endpoint: 'https://some-random-api.ml/facts/dog'})} 等等。

    最好的方法是让Animal 拥有它自己的组件并将getFact 函数作为参数传递,不要忘记在这种情况下你需要绑定它,否则它会失去这个上下文。

    【讨论】:

      猜你喜欢
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2021-05-25
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多