【问题标题】:Using .map() with useEffect and Api将 .map() 与 useEffect 和 Api 一起使用
【发布时间】:2020-03-08 22:12:44
【问题描述】:

我正在尝试使用 useEffect 从 API 中获取一些数据。我成功地获取了数据,但是在设置状态并尝试通过它进行映射后,我只得到“无法读取未定义的映射”。我认为问题在于它在获得响应之前正在运行我的 .map() 代码。我只是不确定如何解决这个问题

这是 api 响应:

data: {count: 87, next: "https://swapi.co/api/people/?page=2", previous: null, results: Array(10)}

这是我的代码

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
import CharacterMap from './characterMap'

const App = () => {
  let [getChars, setChars] = useState(0);
  useEffect(() => {
    axios.get(`https://swapi.co/api/people/`)
      .then(res => setChars(res) )
  },[]);
 console.log(getChars.data.map((e) => e))
  return (

    <div className="App">
      <CharacterMap info={getChars} />
    </div>
  );
}
export default App;

【问题讨论】:

  • map 调用的目的是什么?它只是创建一个具有相同信息的新数组,就像slice() 一样。
  • 在 .map 工作后,我将使用它来提取更多数据。
  • 明白了。 FWIW,我认为您想要res =&gt; setChars(res.data.results)res =&gt; setChars(res.results)(这是在您将useState 中的0 更改为[] 之后,所以它始终是一个数组)。这也可能是您提取所需数据的地方,而不是稍后。所以res =&gt; setChars(res.data.results.map(/*...*/)).
  • 另外,getChars 这个名字使它看起来像一个函数。既然是数据,我建议就叫它chars

标签: javascript reactjs use-effect


【解决方案1】:

axios.get 是一个异步函数,您正试图在尚未完成的异步函数之外获取数据。

您可以使用useEffect 和等于componentDidUpdate 的依赖数组来获取数据。

使用您期望的相同数据类型初始化状态,在这种情况下,我们期望您使用空数组初始化一个数组。

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
import CharacterMap from './characterMap'

const App = () => {
  let [chars, setChars] = useState([]);
  useEffect(async () => {
    try{ 
      let response = await axios.get(`https://swapi.co/api/people/`)
      let data = await response.json();
      setChars(data);
    } catch(error) {
       console.error(error.message);
    }
  },[]);
 // If you want to access the updated state then use this.
  useEffect(() => {
     let newState = chars.map((e) => e); // map your state here
     setChars(newState); // and then update the state
     console.log(newState);
  },[getChars]);

  return (

    <div className="App">
      <CharacterMap info={chars} />
    </div>
  );
}
export default App;

每个state 更新上的第二个useEffect 挂钩触发器,因此您可以在此处获取更新后的state

它还会触发re-render,所以你也可以在return语句中使用map

或者您可以更新axios 响应上的数据,然后设置state推荐

useEffect(async () => {
    try{ 
      let response = await axios.get(`https://swapi.co/api/people/`)
      let data = await response.json();
      let newState = data.map((e) => e); // map your state here
      setChars(newState); // and then update the state
      console.log(newState);
    } catch(error) {
       console.error(error.message);
    }
  },[]);

【讨论】:

  • 谢谢!出于某种原因,我认为您不能在每个页面上多次使用 useEffect!
  • 您可以根据需要多次添加useEffect。
【解决方案2】:

将默认值保留为数组

let [getChars, setChars] = useState([]);

【讨论】:

    【解决方案3】:

    您正在将数据设置为数组chars。而不是你得到响应的那个 set array(results)。

    正如你定义的let [getChars, setChars] = useState([]);

    useEffect(async () => {
        axios
        .get(`https://swapi.co/api/people/`)
        .then(res=> setChars(res.data.results))
        .catch(err=> console.log(err))
      },[]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2020-08-02
      • 2019-05-16
      • 2016-12-20
      • 2020-07-18
      • 1970-01-01
      • 2010-10-22
      相关资源
      最近更新 更多