学习者问题:为什么编码时需要使用单独的 props 文件 Typescript/React?

Learner Question: Why is there a need to use a separate props file when coding Typescript/React?

我正在重新学习(!)TypeScript,并且在最初以简单的方式学习东西后,在较小程度上 React。

我对单独的道具和状态文件的需求感到困惑,特别是它们如何与父组件和子组件一起使用以及父组件或子组件如何利用它们。我认为我的主要问题是理解 TypeScript 以及如何使用 props 和 state。

我正在创建一个如下所示的应用程序:

import * as React from 'react';
import styles from './Dibf.module.scss';
import { HashRouter as Router, Route } from 'react-router-dom';
import { Page1 } from './Page1/Page1';
import { Page2 } from './Page2/Page2';
import { Header } from './Header/Header';
import { Footer } from './Footer/Footer';
import { Product } from './Product/Product';

import { IDibfProps } from './IDibfProps';
import { escape } from '@microsoft/sp-lodash-subset';

export default class Dibf extends React.Component<IDibfProps, {}> {
  constructor(props) {
    super(props);
    this.state = {
      CurrentUserTitle: null,
      CurrentUser: null,
      CurrentUserGroups: null,
      CurrentUserID: null,
      CurrentUserEmail: null,
      FullName: null,
      UniId: null,
      FilteredItems: [],
      Author: null,
      CurrentUserRole: null,
      Items: [],
      DepartmentsList: [],
      SelectedDept: undefined,
      Id: null,
      JobRef: null,
      Title: null,
      JobTitle: null,
      DateOfBreach: null,
      DateOfDiscovery: null,
      IncidentDetails: null,
      PersonalData: null,
      FormStatus: null,     
      PhoneNo: null,
      Department: null,
      SubDepartment: null,
      LoggedInUser: null,
      LoggedInUserPPDefaultItems: [],
    };
  }
  public render(): React.ReactElement<IDibfProps> {
    return (
      <Router>
        <div>
          <h2>App</h2>

          <Header HOW WOULD I GET THIS CHILD FUNCTION TO UPDATE THE STATE OF ITS THIS PARENT?/>

          {/* The different screens will be re-rendered here */}

          <Route path="/screen1" component={Page1} />
          <Route path="/screen2" component={Page2} />
          <Route path="/products/:id" component={Product} />

          <Footer />
        </div>
      </Router>
    );
  }
}

所以你可以看到不同的子组件。 , 等...

我将在这些子组件中的每一个上都有构造 UI 字段和控件。 什么最容易做?:

  1. 在父级中拥有所有控件的状态,就像我在上面所做的那样,然后使用 props 和状态接口文件以某种方式将控件中更改的任何内容传递到状态(提升状态使用处理函数?)

  2. 或者为每个子组件设置状态并在兄弟姐妹之间传递道具?单独的 props/state 接口文件在那种情况下如何工作?

我了解如何使用 React 传递 props/state 但我不了解 TypeScript 如何使用接口进行传递。我猜这与 class 和渲染声明有关但不确定。

我需要这个社区的一些帮助,因为我现在有点紧张。想象一下学了几个月的东西然后发现你什么都不懂!

有人可以通过代码示例向我提供简单的解释,而不是提供链接吗?

谢谢

更新:我已经更新了代码 - 请查看带请求的 Header 函数。请提供代码示例。

T

需要特别指出的是Typescript是duck-typed的。这两个接口是等价的

interface PorpsOne{     
  caption:string     
} 

interface PropsTwo{     
  caption:string     
} 

给定这些接口,以下构造就可以了。

function userOne(item:PropsOne){return item.caption;} 
function userTwo(item:PropsTwo){return item.caption;} 


const item = {caption:"Item caption", other:42, properties:null}; 
userOne(item); 
userTwo(item); 

话虽如此,您可以多次定义您希望与子组件一起使用的属性,每个组件文件一次。您也可以提取公共部分,定义一次,然后将其导入父组件文件和每个子组件文件中。

Typescript 不会在父子之间传递状态,运行-time javascript 会。 Typescript 可帮助您确保通过键入和检查这些类型来传递所需的信息

INHO 尝试提取共享状态并将其放入父级并使用 (1) 处理函数来更新它是一个很好的方向。

因此

HOW WOULD I GET THIS CHILD FUNCTION TO UPDATE THE STATE OF ITS THIS PARENT?

interface HeaderCanChangeCurrentUser{
  onCurrentUserTitle(title: string): void;
}
//...can be a field of parent class instead of const in render
const onCurrentUserTitle:HeaderCanChangeCurrentUser["onCurrentUserTitle"] = (value:string)=>{this.setState({CurrentUserTitle:value});};
<Header onCurrentUserTitle={onCurrentUserTitle}/>

Typescript 帮助您制定组件依赖于状态的哪一部分。

但是又一次。将接口声明放在单独的文件中不是强制性的。声明也可以从组件文件中导出。然而,分开的东西有点有助于可读性,或者不是吗?毕竟是个人和团队的喜好。

我也可以用另一种方式来解释这个问题。打字稿会帮助我为子组件声明道具以更新父状态。也就是说,如果我有一个充满字段的接口,它会创建 "derived/dependent" 充满 onXxx 方法的接口来更改父状态。是的,它确实。

但又无法将此解释与 "separate files" 部分联系起来。