简体   繁体   English

React Typescript 如何通过类型传递道具

[英]React Typescript how to pass props with types

Trying to get better with Typescript in React尝试在 React 中使用 Typescript 变得更好

I have a super simple app where I have App.tsx with a useState for an array of objects我有一个超级简单的应用程序,其中我有App.tsx和一个用于对象数组的 useState

import List from './components/List';

interface IState{
  name: string
  age: number
}

function App() {

  const [people, setpeople] = useState<IState[]>([
    {
      name: 'Chris',
      age: 20
    },
    {
      name: 'John',
      age: 28
    },
    {
      name: 'Paul',
      age: 23
    }
  ])

  return (
    <div className="App">
      <List people={people}/>
    </div>
  );
}

export default App;

I want to pass this as a prop into another component List.tsx .我想将其作为道具传递给另一个组件List.tsx

interface IProps{
    name: string
    age: number
  }

const List = (people:IProps[]) => {
    return (
        <div>
            {people.map(person => (
                <h2>{person.name}</h2>
            ))}
        </div>
    );
};

export default List;

I have types for the object in App.tsx and I'm trying to use the same types in List.tsx我在 App.tsx 中有App.tsx的类型,我正在尝试在List.tsx中使用相同的类型

The problem in App.tsx at <List people={people}/> on people I get App.tsx中的问题<List people={people}/>我得到的人

Type '{ people: IState[]; }' is not assignable to type 'IntrinsicAttributes & IProps[]'.
  Property 'people' does not exist on type 'IntrinsicAttributes & IProps[]'

How do I pass the data in the prop with types?如何使用类型传递 prop 中的数据?

That is because props is the top level object that contains all props passed into the component, so you should either destructure it, or change the interface:那是因为props是顶层 object ,它包含传递给组件的所有 props,所以你应该解构它,或者更改接口:

Quick fix: destructure props快速修复:解构道具

const List = ({ people }: { people: IProps[] }) => { ... }

Better fix: Change the typing of IProps so It defines the nested people key更好的解决方法:更改IProps的类型,以便它定义嵌套的people

interface IProps{
    people: Array<{
        name: string;
        age: number;
    }>
}

const List = ({ people }: IProps) => { ... }

Suggestion建议

Some additional tip: instead of declaring the same prop interface across two files, which means you need to update them in multiple locations should you change your mind later, you can always make List export the people prop (or actually, the atomised version, say IPerson ) and then let the consuming parent import it instead.一些额外的提示:不要在两个文件中声明相同的道具接口,这意味着如果你以后改变主意,你需要在多个位置更新它们,你总是可以让List导出people道具(或者实际上,原子化版本,比如说IPerson ),然后让消费父级导入它。 An example:一个例子:

// List.tsx
export interface IPerson {
    name: string;
    age: number;
}
interface IProps {
    people: IPerson[];
}
const List = ({ people }: IProps) => { ... }

Then...然后...

// App.tsx
import List, { IPerson } from './components/List';
const [people, setpeople] = useState<IPerson[]>([ ... ]);

By default a react functional component only accept an objet with children propriety as props .默认情况下,反应功能组件仅接受具有children属性的对象作为props But you can extend this, in your case by doing so:但是您可以通过以下方式扩展它:

interface IProps{
    name: string
    age: number
  }

const List:React.FC<Iprops[]> = ({people}) => {
    return (
        <div>
            {people.map(person => (
                <h2>{person.name}</h2>
            ))}
        </div>
    );
};

export default List;

You can export your interface in the first file, and then import it in the second file您可以在第一个文件中导出您的界面,然后在第二个文件中导入它

export interface IState{
  name: string
  age: number
}

And the to use the same interface in List.tsx.,并且在 List.tsx 中使用相同的接口,

import { IState} from './List';

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

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