为什么我的 React 应用程序在我 运行 时消失了

Why does my React app disappear when I run it

每当我在页面上获取数据时,几秒钟后,我的整个 React 应用程序就会消失,因为 html 中的根 div 完全是空的,就像这样 <div id="root"></div>仿佛什么都没有。即使我创建了一个新项目,这种情况也发生在我所有其他项目上,即使不添加任何逻辑,这种反应的消失有时也会发生,它拒绝呈现普通 html。我现在在控制台上的这个当前项目上得到的错误是这个

characters.map is not a function

我不知道是什么原因造成的,但我的代码现在看起来像这样,从 App.js 文件开始。我正在从 api.

中提取数据
import {BrowserRouter, Route, Routes} from "react-router-dom"
import Home from "./components/Home";

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

然后是 CharactersListing 页面,该页面应该呈现节目中的所有角色

import React, {useEffect, useState} from 'react'
import CharacterCard from './CharacterCard'

export default function BadListings() {
    const [characters, setCharacters] = useState([])
    
    useEffect(() => {
        const getData = async () => {
            await fetch("https://www.breakingbadapi.com/api/characters")
                .then(response => {
                    setCharacters(response.json());
                    console.log(characters);
                })
                .catch(err => console.log("There must have been an error somewhere in your code", err.message));
        }
        getData();
    });
    
    
  return (
    <div className='container'>
        {characters.map(character => (
            <div>
                <CharacterCard name={character.name} status={character.status} image={character.img} />
            </div>
        ))}
    </div>
  )
}

最后,CharacterCard.js

import React from 'react'
import "../styles/styles.css"

export default function CharacterCard({name, status, image}) {
  return (
    <div className='card'>
        <h1>{name}</h1>
        <h2>{status}</h2>
        <img src={image} alt="umfanekiso" className='imgur' />
    </div>
  )
}

我不知道是什么原因造成的。我从来没有遇到过这个问题它今天才开始。可能是什么原因造成的

characters 是一个字符串,而字符串没有 .map() 方法,这就是 React 崩溃的原因。由于 React 崩溃了,它无法将生成的 HTML 挂载到 #root.

您可以使用[...strings]来使用.map()方法。

在控制台中查找错误的本能。

Umut Gerçek 的回答是正确的,但我要添加一个额外的建议:如果你要 map 处理某事,你应该在状态中将其实例化为可以映射的事物。将其初始状态设置为数组:

const [characters, setCharacters] = useState([])

注意 setter 中的大写字母 'C';那是 useState 惯例。

然后按照您当前的操作设置字符:

setCharacters(response.json());

并且无论 fetch 的结果如何,您的地图都应该可以正常工作,并且还可以处理多个项目。

您导出的是 CharacterCards 而不是 BadCards。

请将您的 CharactersListing 页面中的所有 BadCards 更改为 CharacterCards

有说明

问题

问题是您没有将 characters 状态设置为您认为的状态。 response.json() returns 一个 Promise 对象,并且没有 map 属性 作为要调用的函数。

useEffect 挂钩也缺少依赖项,因此任何触发此 BadListings 组件重新渲染的东西也会重新触发此 useEffect 挂钩,它会更新状态并触发另一个重新渲染。该代码可能会呈现循环。

解决方案

  • 代码应该等待 response.json() Promise 解析并将 that 结果值传递给 characters 状态更新函数。请注意,我还重写了使用 async/awaittry/catch 的逻辑,因为通常认为 anti-pattern 将 async/await 与 Promise 链混合使用。
  • 将依赖数组添加到 useEffect 挂钩。由于我没有看到任何依赖项使用空数组,因此效果仅在组件安装时运行一次。

承诺链示例:

useEffect(() => {
  fetch("https://www.breakingbadapi.com/api/characters")
    .then(response => response.json()) // <-- wait for Promise to resolve
    .then(characters => setCharacters(characters)
    .catch(err => {
      console.log("There must have been an error somewhere in your code", err.message)
    });
}, []); // <-- add empty dependency array

async/await 示例:

useEffect(() => {
  const getData = async () => {
    try {
      const response = await fetch("https://www.breakingbadapi.com/api/characters");
      const characters = await response.json(); // <-- wait for Promise to resolve
      setCharacters(characters);
    } catch(err) {
      console.log("There must have been an error somewhere in your code", err?.message);
    };
  }
  getData();
}, []); // <-- add empty dependency array

不要忘记为映射的字符添加 React 键:

{characters.map((character) => (
  <div key={character.char_id}> // <-- Add React key to outer element
    <CharacterCard
      name={character.name}
      status={character.status}
      image={character.img}
    />
  </div>
))}