简体   繁体   English

设置 State 当 useEffect 中的获取响应是一个数组时

[英]set State when fetch response in useEffect is a array

This is fetching from Pokemon API which response with an array that I want to pass useState variable initialized as empty array with setValue function.这是从 Pokemon API 获取的,它响应一个数组,我想传递 useState 变量,初始化为空数组,setValue function。

React component is below:反应组件如下:

import React, { useState, useEffect } from "react";

export default function Pokemones() {
  const [pokemons, setPokemons] = useState([]);

  useEffect(() => {
    async function fetchData() {
      // Call fetch
      const res = await fetch("https://pokeapi.co/api/v2/pokemon/");
      // Pull out the data
      const json = await res.json();
      // Save the data to array
      console.log(json.results);
 }

    fetchData();
  }, []);

  return (
    <ul>
      {pokemons.map((pokemon) => (
        <li>
          <p>Name = {pokemon.name}</p>
          <p>URL = {pokemon.name}</p>
        </li>
      ))}
    </ul>
  );
}

I tried directly set setPokemons(json.results);我试过直接设置setPokemons(json.results); or by json.results.map , received same error.或通过json.results.map ,收到相同的错误。 I did other tries but I got similar errors我做了其他尝试,但我遇到了类似的错误

      // atfet console.log and before fetchData function 

      let pok = [];
      json.results.map((p) => (pok = [...pok, p]));
      console.log(pok);
      setPokemons(pok);
    }

The error received on consola is:在 consol 上收到的错误是:

Uncaught Error: Objects are not valid as a React child (found: object with keys 
{name, url}). If you meant to render a collection of children, use an array instead.

I guess that array is not passing to variable pokemons but I am able to see in console the array.我猜这个数组没有传递给变量pokemons ,但我可以在控制台中看到数组。 what part is that I am missing.我缺少什么部分。 thanks谢谢

I hope this helps.我希望这有帮助。

import React, { useState, useEffect } from "react";
    
    export default function Pokemones() {
      const [pokemons, setPokemons] = useState([]);
    
      useEffect(() => {
        async function fetchData() {
          // Call fetch
          const res = await fetch("https://pokeapi.co/api/v2/pokemon/");
          // Pull out the data
          const json = await res.json();
          // Save the data to array
          console.log(json.results);
          setPokemons(json.results);
     }
    
        fetchData();
      }, []);
    
      return (
        <ul>
          {pokemons.map((pokemon, index) => {
           return <li key={index}>
              <p>Name = {pokemon.name}</p>
              <p>URL = {pokemon.name}</p>
            </li>
          })}
        </ul>
      );
    }

minimum example最小的例子

Here's a minimum working example you can run here and verify the results in your own browser.这是您可以在此处运行并在您自己的浏览器中验证结果的最小工作示例。

 function App() { const [pokemon, setPokemon] = React.useState([]) React.useEffect(_ => { fetch("https://pokeapi.co/api/v2/pokemon/").then(res => res.json()).then(res => setPokemon(res.results)).catch(console.error) }, []) return <ul> {pokemon.map(p => <li key={p.name}> <a href={p.url}>{p.name}</a> </li> )} </ul> } ReactDOM.render(<App/>, document.querySelector("#app"))
 ul { list-style-type: none; padding-left: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script> <div id="app"></div>

going further走得更远

We can expand the app's functionality a bit by making the list item's clickable and show the selected Pokémon details -我们可以通过使列表项可点击并显示选定的神奇宝贝详细信息来扩展应用程序的功能 -

pokedex app screenshot pokedex 应用程序截图
图鉴预览

To do this we break the program down into three parts.为此,我们将程序分为三个部分。 First, the List component -首先, List组件——

function List({ pokemon, onClick }) {
  return <ul id="list">
    {pokemon.map(p =>
      <li key={p.name} onClick={onClick(p)}>
        {p.name}
      </li>
    )}
  </ul>
}

Second, the Details component -二、 Details组件——

function Details({ url }) {
  const [data, setData] = React.useState(null)
  
  React.useEffect(_ => {
    url && fetch(url)
      .then(res => res.json())
      .then(res => setData(res))
      .catch(console.error)
  }, [url])
  
  return data
    ? <pre id="details">
        <h3>{data.name}</h3>
        {JSON.stringify(data, null, 2)}
      </pre>
    : <pre id="details"><h3>Select a Pokémon in the list</h3></pre>
}

And finally the Pokedex component which brings it all together -最后是Pokedex组件,它把这一切结合在一起——

function Pokedex() {
  const [pokemon, setPokemon] = React.useState([])
  const [selected, setSelected] = React.useState(null)
  
  const selectPokemon = pokemon => event =>
    setSelected(pokemon.url)
  
  React.useEffect(_ => {
    fetch("https://pokeapi.co/api/v2/pokemon/")
      .then(res => res.json())
      .then(res => setPokemon(res.results))
      .catch(console.error)
  }, [])
  
  return <div id="pokedex">
    <List pokemon={pokemon} onClick={selectPokemon} />
    <Details url={selected} />
  </div>
}

Hopefully this gives you a better idea of how React apps are put together.希望这能让你更好地了解 React 应用程序是如何组合在一起的。 You can run the Pokedex demo below -您可以在下面运行Pokedex演示 -

 function Pokedex() { const [pokemon, setPokemon] = React.useState([]) const [selected, setSelected] = React.useState(null) const selectPokemon = pokemon => event => setSelected(pokemon.url) React.useEffect(_ => { fetch("https://pokeapi.co/api/v2/pokemon/").then(res => res.json()).then(res => setPokemon(res.results)).catch(console.error) }, []) return <div id="pokedex"> <List pokemon={pokemon} onClick={selectPokemon} /> <Details url={selected} /> </div> } function List({ pokemon, onClick }) { return <ul id="list"> {pokemon.map(p => <li key={p.name} onClick={onClick(p)}> {p.name} </li> )} </ul> } function Details({ url }) { const [data, setData] = React.useState(null) React.useEffect(_ => { url && fetch(url).then(res => res.json()).then(res => setData(res)).catch(console.error) }, [url]) return data? <pre id="details"> <h3>{data.name}</h3> {JSON.stringify(data, null, 2)} </pre>: <pre id="details"><h3>Select a Pokémon in the list</h3></pre> } ReactDOM.render(<Pokedex/>, document.querySelector("#app"))
 body, ul, pre { margin: 0; padding: 0; } ul { list-style-type: none; } li { cursor: pointer; } #pokedex { display: flex; } #list { margin-right: 2rem; } #details { flex-grow: 1; background-color: #ffc; max-height: 100vh; overflow-y: scroll; padding-left: 1rem; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script> <div id="app"></div>

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

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