简体   繁体   English

单击按钮时显示来自 API 的数据。 使用 ReactJS

[英]Display data from an API when clicking a button. Using ReactJS

I am trying to display the data of each character when I click the Info Button.当我单击信息按钮时,我试图显示每个字符的数据。 I know it is because in the onButtonClickHandler function it can not see the state.我知道这是因为在onButtonClickHandler函数中它看不到状态。 I have also tried this.state.person but it gives me an error saying "can not read state".我也试过this.state.person但它给了我一个错误,说“无法读取状态”。 And if I try just state.person it will give me "undefined".如果我只尝试state.person它会给我“未定义”。

What is the best way to do that?最好的方法是什么? Thank you谢谢

API Link: https://swapi.dev/people/ API 链接: https : //swapi.dev/people/

import React from "react";

export default class FetchActors extends React.Component {
  state = {
    loading: true,
    person: null
  };

  async componentDidMount() {
    const url = "https://swapi.dev/api/people/";
    const response = await fetch(url);
    const data = await response.json();
    this.setState({ person: data.results, loading: false });
  }

  render() {
    if (this.state.loading) {
      return <div>loading...</div>;
    }

    if (!this.state.person.length) {
      return <div>didn't get a person</div>;
    }

   function onButtonClickHandler(state) {
      console.log(state.person);
    };


    return (
      <div>
        <h1>Actors</h1>
        {this.state.person.map(person =>(
        <div>
          <div>
            {person.name}
            <button onClick={onButtonClickHandler}>Info</button>

          </div>

        </div>
        ))}
        <button onClick={onButtonClickHandler}>Enter</button>
      </div>
    );
  }
}

Please correct me if I'm wrong如果我错了,请纠正我

The most likely reason why you are seeing this is because of the way javascript internally works.您看到这种情况的最可能原因是 javascript 内部的工作方式。 The syntax:语法:

function xyz() {

}

has an implicit this有一个隐含的this

Maybe try changing your code from:也许尝试从以下位置更改您的代码:

function onButtonClickHandler(state) {
  console.log(state.person);
};

to:到:

const onButtonClickHandler = () => {
  console.log(this.state.person);
};

Further Reading: Here延伸阅读: 这里

there are a few ways you can resolve your issue;有几种方法可以解决您的问题; I'll give you the more common approach.我会给你更常见的方法。

  1. You want to define your click handler as a class (instance) method, rather than declare it as a function inside the render method (you can define it as a function inside the render method, but that's probably not the best way to do it for a variety of reasons that are out of scope).您想将点击处理程序定义为类(实例)方法,而不是将其声明为渲染方法内的函数(您可以将其定义为渲染方法内的函数,但这可能不是最好的方法)超出范围的各种原因)。
  2. You will also have to bind it's 'this' value to the class (instance) because click handlers are triggered asynchronously.您还必须将它的“this”值绑定到类(实例),因为单击处理程序是异步触发的。
  3. Finally, add a button and trigger the fetch on click:最后,添加一个按钮并在点击时触发获取:
class Actors extends React.Component {
  state = {
    loading: false,
    actors: undefined,
  };

  constructor(props) {
    super(props);
    this.fetchActors = this.fetchActors.bind(this);
  }

  async fetchActors() {
    this.setState({ loading: true });
    const url = "https://swapi.dev/api/people/";
    const response = await fetch(url);
    const data = await response.json();
    this.setState({ actors: data.results, loading: false });
  }

  render() {
    console.log('Actors: ', this.state.actors);
    return <button onClick={this.fetchActors}>fetch actors</button>;
  }
}

You have defined your function onButtonClickHandler as a function that takes one argument, and logs the person property of that argument.您已将函数onButtonClickHandler定义为接受一个参数并记录该参数的person属性的函数。 The argument state in your function has nothing to do with the state of your component.函数中的参数state与组件的state无关。 As javascript sees it, they are two totally unrelated variables which just happen to have the same name.正如 javascript 所见,它们是两个完全不相关的变量,只是碰巧具有相同的名称。

function onButtonClickHandler(state) {
   console.log(state.person);
};

When button calls onClick , it passes the event as the argument.button调用onClick ,它将事件作为参数传递。 So your onButtonClickHandler is logging the person property of the event, which obviously doesn't exist.所以你的onButtonClickHandler正在记录事件的person属性,这显然不存在。

Since you are not using any information from the event, your function should take no arguments.由于您没有使用事件中的任何信息,因此您的函数不应采用任何参数。 As others have said, you should also move this function outside of the render() method so that it is not recreated on each render.正如其他人所说,您还应该将此函数移到render()方法之外,以便不会在每次渲染时重新创建它。 The suggestion to use bind is not necessary if you use an arrow function, since these bind automatically.如果您使用箭头函数,则不需要使用bind的建议,因为它们会自动绑定。

export default class FetchActors extends React.Component {
  /*...*/

  onButtonClickHandler = () => {
     console.log(this.state.person);
  };

}

Inside render()内部render()

<button onClick={this.onButtonClickHandler}>Enter</button>

You could also define the function inline, as an arrow function which takes no arguments:您还可以将函数内联定义为不带参数的箭头函数:

<button onClick={() => console.log(this.state.person)}>Enter</button>

If you are new to react, I recommend learning with function components rather than class components.如果您不熟悉 React,我建议您使用函数组件而不是类组件来学习。

Edit:编辑:

Updating this answer regarding our comments.更新有关我们评论的答案。 I was so caught up in explaining the errors from doing the wrong thing that I neglected to explain how to do the right thing!我太忙于解释做错事的错误,以至于忽略了解释如何做正确的事!

I am trying to display the data of each character when I click the Info Button.当我单击信息按钮时,我试图显示每个字符的数据。

Once we call the API, we already have the info loaded for each character.一旦我们调用 API,我们就已经为每个角色加载了信息。 We just need to know which one we want to display.我们只需要知道我们想要显示哪一个。 You can add a property expanded to your state and use it to store the index (or id or name , whatever you want really) of the currently expanded item.您可以添加一个expanded到您的state的属性,并使用它来存储当前扩展项目的索引(或idname ,无论您想要什么)。

When we loop through to show the name and info button, we check if that character is the expanded one.当我们循环显示名称和信息按钮时,我们检查该字符是否是展开的字符。 If so, we show the character info.如果是这样,我们会显示字符信息。

Now the onClick handler of our button is responsible for setting state.expanded to the character that we clicked it from.现在我们按钮的onClick处理程序负责将state.expanded设置为我们单击它的字符。

{this.state.person.map((person, i) =>(
<div>
  <div>
    {person.name}
    <button onClick={() => this.setState({expanded: i})}>Info</button>
    {this.state.expanded === i && (
      <CharacterInfo
        key={person.name}
        person={person}
      />
    )}
  </div>

CodeSandbox Link代码沙盒链接

Sometimes i takes react a min to load the updated state.有时我需要一分钟的时间来加载更新的状态。

import React from "react";

export default class FetchActors extends React.Component {
  state = {
    loading: true,
    person: null
  };

  async componentDidMount() {
    const url = "https://swapi.dev/api/people/";
    const response = await fetch(url);
    const data = await response.json();
    if(!data.results) { // throw error }
    this.setState({ person: data.results, loading: false }, () => {
  console.log(this.state.person) // log out your data to verify
});
  }

  render() {
    if (this.state.loading || !this.state.person) { // wait for person data
      return <div>loading...</div>;
    }else{


   function onButtonClickHandler(state) { // just make a componentDidUpdate function
      console.log(state.person);
    };


    return (
      <div>
        <h1>Actors</h1>
        {this.state.person.map(person =>(
        <div>
          <div>
            {person.name}
            <button onClick={onButtonClickHandler}>Info</button>

          </div>

        </div>
        ))}
        <button onClick={onButtonClickHandler}>Enter</button>
      </div>
    );
  }
}}

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

相关问题 单击按钮后如何显示来自mongodb的数据到reactjs? - How to display data coming from mongodb to reactjs after clicking the button? jQuery按钮。 单击图标时删除 - jQuery button. Remove when clicking icon 防止反应路由器在按下返回按钮时重新加载 API 调用。 Reactjs - Prevent react router reloading API call when pressing back button. Reactjs 单击ReactJS中的按钮时如何动态显示html内容? - How to display html content dynamically when clicking a button in ReactJS? 单击按钮从外部获取天气数据时出现问题 API - problem when clicking a button to fetch weather data from outside API 如何使用reactjs在表中显示从api获取的数据 - how to display data getting from an api in table using reactjs 使用Reactjs单击显示按钮时如何渲染滤过国家? - How to render filitered countries when clicking the show button using Reactjs? ReactJS显示来自Wordpress API的数据 - ReactJS display data from Wordpress API 当我按下按钮时如何将数据从一个组件发送到另一个组件。 React.js - how to send the data from one component to another component when i press a button. React.js 单击按钮时如何显示来自特定API的新随机生成的报价? - How to display a newly randomly generated quote from a specific API when clicking a button?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM