繁体   English   中英

为什么我不能使用 useState() 将数组设置为 API 数据?

[英]Why can't I set an array to API data using useState()?

所以我有一个使用电影 API 的应用程序。 我提出了一个 API 请求,然后我使用 useState 挂钩将此数据传递给一个数组,基本上我的代码如下所示:

const App = () => {

type MovieType = {    //declaring type
    rate: string,
    title: string,
    tagline: string,
    date: string,
};

 interface MovieProps {   //extending an interface with MovieType
 movies: MovieType[],
  }
  const [movies, setMovies] = useState<MovieType[]>([]);   //useState for setting an array to data from api

  useEffect(() =>{
      fetchMovies();
  }, [])

  async function fetchMovies() {   //function for fetching movies
      try{
        let apikey = '{api_key}';
        let url: string = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=';
        url = url + apikey;
        const response = await axios.get<[MovieType]>(url);
        setMovies(response.data);
      }catch(e){
        alert('Error');
      }
  }

  return (
    <div className="App">
      <Header/>
      <Hero movies={movies}/>
    </div>
  );
}

所以基本上,当我运行应用程序时,我会收到一个错误警报。 我尝试重命名 useState,因此它与<Hero>组件中的道具不同,然后我可以将数据传递给数组。 但是当我用[movies, setMovies]来做这件事时,它就不起作用了。 所以我猜问题出在传递道具或type MovieType的某个地方,但我无法弄清楚究竟是什么问题。

编辑:我在尝试捕获时遇到的错误:

TypeError: movies.map is not a function

我在Container组件中有movies.map ,它从Hero那里获取电影,从App中获取它:

const Container = ({movies}: MovieProps) => {
  return (
    <div className="container">
      {movies.map((movie) =>(
          <MovieItem movie={movie} key={movie.title}/>
      ))}
    </div>
  );
};

我不知道为什么movies.map不是 function 如果电影基本上是一个数组。

您必须添加“await fetchMovies”而不仅仅是“fetchMovies”,但由于您不能使 useEffect 异步尝试这样的事情......

 useEffect(() =>{
      async function foo(){
        await fetchMovies();
     }
      foo();
  }, []);

希望它有效!

问题是Container组件在fetchMovies完成获取数据之前尝试迭代movies 本质上,您正在尝试迭代一个空数组。 为了揭示这一点,并为了将来的调试目的,在Container中包含一个console.log(movies)

要解决此问题,只需在 map 对数据进行检查之前将movies.length作为检查:

const Container = ({movies}: MovieProps) => {
  return (
    <div className="container">
      {movies.length && movies.map((movie) =>(
          <MovieItem movie={movie} key={movie.title}/>
      ))}
    </div>
  );
};

暂无
暂无

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

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