在React中使用map()时无法从API调用访问数组数据

时间:2019-10-30 00:59:00

标签: javascript arrays reactjs

我正在尝试映射从API调用接收到的数据。使浅端点正常工作,但嵌套的任何东西都会给我一个错误。

目标是获取所有开头主题并将其显示在“ ul”中。

确切的错误“ TypeError:anime.opening_themes未定义”

Repo to the project

在这里端点。

enter image description here

这里是我的组件。

const AnimeDetails = (props) => {
  const API = 'https://api.jikan.moe/v3/anime'

  const initialState = {
    anime: []
  }

  const [anime, setAnime] = useState(initialState)

  useEffect(() => {
    const getAnime = async () => {
      const response = await fetch(`${API}/${props.match.params.animeId}`)
      const data = await response.json()

      console.log(data);
      setAnime(data) // set initial state to hold data from our API call
    }
    getAnime()
  }, []) // [] prevents useEffect from running in an infinite loop

  return (
    <AnimeDetailsWrapper>
      <Title>{anime.title}</Title>
      <Details>
        {anime.opening_themes
          .map((song, index) => (
            <li key={index}>{song}</li>
          ))}
      </Details>
    </AnimeDetailsWrapper>
  )
}

3 个答案:

答案 0 :(得分:2)

您的初始状态是一个空数组,而不是一个空对象:

const initialState = {
  anime: []
}

安装组件时,尚无数据,因此您尝试呈现[].opening_themes.map,并且在空数组上显然没有opening_themes属性。

将您的初始状态设置为空对象:

const initialState = {}

您可能想要在尝试呈现数据之前先测试是否有数据:

return anime.mal_id && (
    <AnimeDetailsWrapper>
      <Title>{anime.title}</Title>
      <Details>
        {anime.opening_themes
          .map((song, index) => (
            <li key={index}>{song}</li>
          ))}
      </Details>
    </AnimeDetailsWrapper>
  )

这将阻止您的组件呈现任何内容,直到您的anime状态包含一个mal_id属性为止。

答案 1 :(得分:0)

第一次渲染组件时,状态anime等于{anime: []},它没有名为opening_themes的属性。

答案 2 :(得分:0)

您应该尝试这样

首先,删除initialState代码并使用直接代码,如下所示

如果响应为数组形式

const [anime, setAnime] = useState([])

如果响应是对象形式的

const [anime, setAnime] = useState({})

否则,null将适用于任何响应

const [anime, setAnime] = useState(null)

返回这样的代码

 return (
  <>  {anime && <AnimeDetailsWrapper>
      <Title>{anime.title}</Title>
      <Details>
        {anime.opening_themes
          .map((song, index) => (
            <li key={index}>{song}</li>
          ))}
      </Details>
    </AnimeDetailsWrapper>}</>
  )