【问题标题】:How to pass an object to a custom child component in ReactJS using Typescript?如何使用 Typescript 将对象传递给 ReactJS 中的自定义子组件?
【发布时间】:2020-12-11 07:01:41
【问题描述】:

目标

我想通过useEffect() 获取应用程序根组件中的数据(并将它们设置为状态),然后将状态传递给我的自定义组件。我可以用 JS 做到这一点,但同样的步骤不适用于 Typescript。

我的错误信息如下:

Type '{ obj: Person; }' is not assignable to type 'IntrinsicAttributes 
& Person & { children?: ReactNode; }'. Property 'obj' does not exist 
on type 'IntrinsicAttributes & Person & { children?: ReactNode; }'.TS2322

对我来说,看起来我有一个 Person 类型的对象,我无法分配给其他类型的 Person...

App.tsx

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

export interface Person {
  name: string;
  email: string;
  dob: string;
  address: string;
  number: string;
  userName: string;
  pssw: string;
};

const initPerson: Person = {
  name: "",
  email: "",
  dob: "",
  address: "",
  number: "",
  userName: "",
  pssw: ""
};

const App: React.FC = () => {
  const [ profile, setProfile ] = useState<Person>(initPerson)

  useEffect(() => {
    // logic for fetching data and setting the state
  }, []);

  return (
    <div id="app">
      <h1>Random user generator</h1>
      <div id="content">
        <Profile obj={profile} />
    </div>
  );
}

export default App;

Person.tsx

import React from 'react';
import { Person } from './app/App'

const Profile: React.FC<Person> = (props) => {
    return (
        <div id="Card">
            {/* photo */}
            <div id="photo"><img src="" alt="profile" /></div>
            {/* name */}
            <div id="name"></div>
            {/* email */}
            <div id="email"></div>
            {/* dob */}
            <div id="dob"></div>
            {/* adress */}
            <div id="address"></div>
            {/* number */}
            <div id="number"></div>
            {/* pssw */}
            <div id="password"></div>
        </div>
    );
}

export default Profile;

我在这里找不到任何相关的 YT 视频或以前的帖子...基于这些问题(herehere)我想我需要声明我的组件的接口?

如果是这样:

  • 在哪里?
  • 如果我已经为要传递给组件的 Person 定义了接口,为什么还需要声明组件的接口?
  • 声明应该是什么样的?
  • 错误告诉我什么?
  • 我应该如何正确地将数据传递给子组件? (以及从孩子到父母)
  • 还有什么我应该知道的吗?

非常感谢任何帮助。谢谢!

【问题讨论】:

    标签: javascript reactjs typescript react-component


    【解决方案1】:

    问题是这个

    const Profile: React.FC<Person>
    

    应该是这样的

    const Profile: React.FC<{ obj: Person }>
    

    也就是说,props 不是Person 类型,你在Profile 中有一个obj 属性,它是Person 类型。

    React.FC&lt;T&gt; 中的类型参数 T 需要是所有自定义道具的形状,在内置 React 道具(即children)之上 - 所以基本上是一个带有字段的对象。

    例如,如果您有另一个道具 foo,它应该是一个数字,它会是 React.FC&lt;{ obj: Person, foo: number }&gt;,等等。

    【讨论】:

    • 您好@davciwill,感谢您的回答。它有帮助。现在我了解了如何为 props 创建一个接口,我正在传递给我的子组件。对于未来的读者,我还想在@Luis Paulo Pinto 的回答中指出他为props 制作接口的地方。
    【解决方案2】:

    你传递的道具形状实际上是

    export interface Person {
      obj: {
        name: string;
        email: string;
        dob: string;
        address: string;
        number: string;
        userName: string;
        pssw: string;
      }
    };
    

    但是你声明了

    export interface Person {
      name: string;
      email: string;
      dob: string;
      address: string;
      number: string;
      userName: string;
      pssw: string;
    };
    

    既然我看你喜欢学习和尝试,那我就让你看看哪里可以调整!如果没有,请告诉我,我会添加更多详细信息。

    【讨论】:

    • 您好,感谢您的帮助。我了解您试图告诉我的内容(并阅读其他答案)。我现在也明白我正在传递obj: Person。好的,我想我现在明白了。在 JS 中,我习惯于解构 props,因此使用 {obj} 而不是 props.obj。这在打字稿中是一样的,我只需要正确定义我传递的所有道具。
    【解决方案3】:

    你可以这样做:

    // Here you create an interface for Profile component that receives an "obj" prop of Person type.
    interface ProfileProps {
      obj: Person;
    }
    
    const Profile: React.FC<ProfileProps> = (props) => {
       console.log(props.obj);
       return (
       ....
    

    现在你会很好,因为当你在 App 组件中设置 Profile 标签时,你正在传递 obj 属性:

    <Profile obj={profile} />
    

    【讨论】:

    • 您好,感谢您的回答。它也绝对有帮助。我的问题是ProfileProps(或者更确切地说是componentName + Props)是强制性命名,或者我是否可以为ProfileProps选择其他随机名称。它是约定还是有其他含义/目的?
    • 嗨 Lukas,它只是我使用的一个约定,对我来说它让代码更具可读性 - 当我看到类似 Profile: React.FC&lt;ProfileProps&gt; 的内容时,我知道这个组件有一些自定义道具。但基本上你可以随心所欲地命名它,并找到一个让你更舒服的约定。
    猜你喜欢
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2020-08-26
    相关资源
    最近更新 更多