简体   繁体   English

如何在 Typescript 中传递道具?

[英]How can I pass props in Typescript?

So I started learning typescript and I can't figure out how to pass props.于是开始学习typescript,不知道怎么传道具。 I have a movie search, so I have a next component chain: App -> Hero(a huge div which displays everything) -> Container(a container which contains divs with movies in each one) -> MovieItem(a div which contains all info about the movie, which we get from the json data).我有一个电影搜索,所以我有一个下一个组件链:App -> Hero(一个显示所有内容的巨大 div)-> Container(一个包含 div 的容器,每个都有电影)-> MovieItem(一个包含所有内容的 div关于电影的信息,我们从 json 数据中获得)。

I made the next interface:我做了下一个界面:

export interface IMovie{
    rate: string;
    title: string,
    tagline: string;
    date: string;
}

Edit: I edited the code from the answers and that's what it looks like now:编辑:我从答案中编辑了代码,这就是现在的样子:

App component:应用组件:

    const App = () => {

  const [movies, setMovies] = useState<MovieProps[]>([]);

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

  async function fetchMovies() {
      try{
        let apikey = '0ce1e51fc4f5b92e2f8984a6aa026503';
        let url: string = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=';
        url = url + apikey;
        const response = await axios.get<MovieProps[]>(url);
        setMovies(response.data);
        console.log(response.data);

      }catch(e){
        alert(e)
      }
  }

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

export default App;

Hero component:英雄组件:

const Hero = ({movies}: MovieProps) => {
  return (
    <div className="hero">
        <h1>trending today</h1>
        <Container movies={movies}/>
    </div>
  );
};

export default Hero;

Container component:容器组件:

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

export default Container;

I passed props all the way through to MovieItem, but here's the problem, in App.tsx component I can't pass the array, because when I try to pass to the Hero component in the following way: <Hero movies={movies}/> , I get the next error:我一直将道具传递给 MovieItem,但问题是,在 App.tsx 组件中我无法传递数组,因为当我尝试通过以下方式传递给 Hero 组件时: <Hero movies={movies}/> ,我得到下一个错误:

Type 'MovieProps[]' is not assignable to type 'MovieType[]'.
  Type 'MovieProps' is missing the following properties from type 'MovieType': rate, title, tagline, date

I created an index.d.ts file to store all the interfaces, it looks like this:我创建了一个index.d.ts文件来存储所有接口,它看起来像这样:

declare module 'myMovies' {
    type MovieType = {
        rate: string,
        title: string,
        tagline: string,
        date: string,
    };

    interface MovieProps {
        movies: MovieType[],
      }
    }

    module.exports = {
        MovieType,
        MovieProps
    };

So I'm not sure what could be the problem, I declared a default array in useState() and tried to pass to the Hero component.所以我不确定可能是什么问题,我在useState()中声明了一个默认数组并尝试传递给 Hero 组件。

Your typings seem to be confusing a single movie and your props type, which has an array of multiple movies.您的打字似乎混淆了单个电影和您的道具类型,后者具有多部电影的数组。

You also don't need an index.d.ts file at all;您也根本不需要index.d.ts文件; in fact you shouldn't have one.事实上你不应该有一个。 (You could export your common types from eg a types.ts file.) (您可以从例如types.ts文件中导出常用类型。)

Here's an example where everything you have is in one file.这是一个示例,您拥有的所有内容都在一个文件中。

import { useState, useEffect } from "react";

interface MovieType {
  rate: string;
  title: string;
  tagline: string;
  date: string;
}

interface MoviesProps {
  movies: MovieType[];
}

function App() {
  const [movies, setMovies] = useState<MovieType[]>([]);
  useEffect(() => {
    setMovies([{ rate: "8", title: "Hello", tagline: "Yes", date: "2021" }]);
  }, []);

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

function Hero({ movies }: MoviesProps) {
  return (
    <div className="hero">
      <h1>trending today</h1>
      <Container movies={movies} />
    </div>
  );
}

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

function MovieItem({ movie }: { movie: MovieType }) {
  return (
    <div className="movie">
      <span className="movie__title">{movie.title}</span>
      <span className="movie__title">{movie.tagline}</span>
      <span className="movie__title">{movie.rate}</span>
      <span className="movie__title">{movie.date}</span>
      <button>Button</button>
    </div>
  );
}

I tend to simply define components' props directly:我倾向于直接简单地定义组件的道具:

const MovieItem = (props: movieProps) => { 
  const { movies } = props;
  ...

I alos notice that you have no 'movies' prop, only a 'movie' prop.我还注意到您没有“电影”道具,只有“电影”道具。 Check your spelling检查你的拼写

try

const MovieItem = ({movies}):({movies:movieProps}) => { 
  return (
    <div>
          {movies.map(movie =>  //and here I have an error Parameter 'movie' implicitly has an 'any' type.
      <div className="movie">
      <span className="movie__title">{movie.title}</span>
        <span className="movie__title">{movie.tagline}</span>
        <span className="movie__title">{movie.rate}</span>
        <span className="movie__title">{movie.date}</span>
        <button>Button</button>
  </div>
      )}
    </div>
  );
};

The problem with declaring props for functional components in Typescript is that the underlying implementation of react expects the props to extend from their native, which is the error you are getting.在 Typescript 中为功能组件声明 props 的问题在于,react 的底层实现期望 props 从它们的原生扩展,这是你得到的错误。

A solution is to describe prop in the component's definition rather passing props interface to the component generator( FC )一种解决方案是在组件的定义中描述 prop,而不是将 props 接口传递给组件生成器( FC

Besides your movies typo mentioned in the comments, you did not assign the props type in the argument.除了评论中提到的movies拼写错误外,您没有在参数中指定道具类型。

import React from 'react'

export interface IMovie{
  rate: string;
  title: string,
  tagline: string;
  date: string;
}

interface movieProps{
  movies: Array<IMovie>
}

const MovieItem = ({movies}: movieProps) => {  //here i have an error `Property 'movies' does not exist on type 'PropsWithChildren<movieProps>`
 return (
   <div>
        {movies.map(movie=>
          <div className="movie">
          <span className="movie__title">{movie.title}</span>
          <span className="movie__title">{movie.tagline}</span>
          <span className="movie__title">{movie.rate}</span>
          <span className="movie__title">{movie.date}</span>
          <button>Button</button>
          </div>
        )}
   </div>
 )
};

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

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