简体   繁体   English

在 API 调用之前 React 钩子组件呈现

[英]React hook component renders before API call

I need to create a React app which let's you list pokemons and types.我需要创建一个 React 应用程序,让你列出 pokemons 和类型。 I fetch data from the PokeAPI.我从 PokeAPI 获取数据。 Is it a good practice to fetch it from the App component and then pass it to the child components, or is it better to fetch them from the child?从 App 组件中获取它然后将其传递给子组件是一个好习惯,还是从子组件中获取它们更好?

I am fetching it in the main app, I can see the fetch works because I console.log the data, but my component doesn't get it, and because of that I get a props.map is not a function in .我在主应用程序中获取它,我可以看到获取工作,因为我 console.log 数据,但我的组件没有获取它,因此我得到一个 props.map is not a function in .

Here is my App.js:这是我的 App.js:

import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";
import axios from "axios";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import PokemonList from "./components/PokemonList";

const App = (props) => {
  const [pokemons, setPokemons] = useState([]);

  const [types, setTypes] = useState([]);

  const [isLoading, setIsLoading] = useState(true);

  const getPokemons = () => {
    const axios = require("axios").default;
    axios.get("https://pokeapi.co/api/v2/pokemon").then(function (response) {
      console.log("Fetched pokemons");
      console.log(response.data.results);
      setIsLoading(false);
      setPokemons(response.data.results);
    });
  };

  const getTypes = () => {
    setIsLoading(true);
    const axios = require("axios").default;
    axios.get("https://pokeapi.co/api/v2/type").then(function (response) {
      console.log("Fetched types");
      console.log(response.data.results);
      setIsLoading(false);
      setTypes(response.data.results);
    });
  };

  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/pokemons" onClick={getPokemons}>
                Pokemons
              </Link>
            </li>
            <li>
              <Link to="/types">Types</Link>
            </li>
          </ul>
        </nav>

        {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
        <Switch>
          <Route path="/pokemons">
            <Pokemons pokemons={pokemons} />
          </Route>
          <Route path="/types">
            <Types />
          </Route>
        </Switch>
      </div>
    </Router>
  );
};

function Pokemons(pokemons) {
  return <PokemonList props={pokemons} />;
}

function Types(typeList) {
  return <h2>TYPES:</h2>;
}

export default App;

Here is my PokemonList.js:这是我的 PokemonList.js:

import React from "react";
import { Card } from "semantic-ui-react";
import PokeCard from "./PokeCard";

const Pokemonlist = (props) => {
  let content = (
    <Card.Group>
      {props.map(function (object, i) {
        return <PokeCard pokemon={object} key={i} />;
      })}
    </Card.Group>
  );

  return content;
};

export default Pokemonlist;

and last here is my PokeCard.js最后是我的 PokeCard.js

import { Card, Image } from "semantic-ui-react";
import React from "react";

const PokeCard = (pokemon) => {
  let content = (
    <Card>
      <Card.Content>
        <Image floated="right" size="mini" src={pokemon.img} />
        <Card.Header>{pokemon.name}</Card.Header>
        <Card.Meta>{pokemon.base_experience}</Card.Meta>
        <Card.Description>ID: {pokemon.id}</Card.Description>
      </Card.Content>
    </Card>
  );

  return content;
};

export default PokeCard;

So the basic idea is:所以基本思路是:

On the main page you click Pokemons button, which calls the fetch then renders the PokemonList component which basically just renders multiple PokeCard components from the data I fetched.在主页上,您单击 Pokemons 按钮,该按钮调用 fetch 然后呈现 PokemonList 组件,该组件基本上只是从我获取的数据中呈现多个 PokeCard 组件。

1, What am I missing here? 1,我在这里缺少什么?

2, In my situation when nothing changes do I need to use useEffect? 2、在我没有任何变化的情况下,我需要使用useEffect吗?

3, When should I fetch the data, and where? 3、我应该什么时候获取数据,在哪里获取?

EDIT: I want to use hooks with zero classes编辑:我想使用零类的钩子

here is a summary of my answer这是我的回答的摘要

  • it is best to fetch some initial data in parent and then make further requests in child component if necessary to save network usage最好在父组件中获取一些初始数据,然后在必要时在子组件中进一步请求以节省网络使用
  • use the useEffect hook to fetch the results before rendering the elements在渲染元素之前使用useEffect钩子获取结果
  • What you are missing is that you are not using props in pokemon and you should put the get call inside useEffect hook in App component because the child component is rendering before the props is passed to it and this is the reason you are getting undefined error您缺少的是您没有在 pokemon 中使用道具,您应该将 get 调用放在App组件的 useEffect 钩子中,因为子组件在道具传递给它之前正在呈现,这就是您收到undefined错误的原因

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

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