reactjs - 如何从继承类覆盖 React.Component 状态类型?

标签 reactjs typescript generics overwrite

我有一个扩展另一个组件的组件类,我正在尝试弄清楚如何覆盖我从中继承的状态类型。

这是一个例子:

class MyComponent extends React.Component<SomeProps, SomeState> {
  // ...
}

class ExtendedComponent extends MyComponent {
  // How to overwrite SomeState?
  // This component needs to store a different model of state.
}

我需要 ExtendedComponent 为它的 state 使用不同的 interface,但我不太清楚如何实现它。


编辑:现在就去某个地方吧!

但是,现在 Parent 充满了与状态修改有关的各种错误。到目前为止,这是我得到的:

interface ParentProps {
  a: string;
}

interface ParentState {
  b: string;
}

class Parent<P, S> extends React.Component<ParentProps & P, ParentState & S> {
  constructor(props) {
    super(props);

    // Type '{ b: "hello"; }' is not assignable to type 'Readonly<ParentState & S>'
    this.state = {
      b: 'hello',
    };
  }

  aFunction(): void {
    /*
      Argument of type '{ b: "testing"; }' is not assignable to parameter of type '(ParentState & S) | ((prevState: Readonly<ParentState & S>, props: Readonly<ParentProps & P>) => (ParentState & S) | Pick<ParentState & S, "b">) | Pick<ParentState & S, "b">'.
  Type '{ b: "testing"; }' is not assignable to type 'Pick<ParentState & S, "b">'.
    Types of property 'b' are incompatible.
      Type '"testing"' is not assignable to type 'string & S["b"]'.
        Type '"testing"' is not assignable to type 'S["b"]'.
    */
    this.setState({
      b: 'testing',
    });
  }
}

interface ChildProps {
  c: string;
}

interface ChildState {
  d: string;
}

class Child extends Parent<ChildProps, ChildState> {
  constructor(props) {
    super(props);

    // This is what I'm after -- and TypeScript doesn't complain :)
    this.state = {
      b: 'hello',
      d: 'world',
    };
  }
}

编辑 2:

回想起来,将近两年后:

扩展另一个组件类 is not recommended由 React 的维护者提供。这是有充分理由的,因为我不得不在一个糟糕的生产应用程序中维护这种方法!我最终使用高阶组件和自定义 Hook 重写了大量代码。

这个用例没有得到很好的支持是有原因的,避免因过度设计组件而导致复杂化!想象一下,您试图向另一位开发人员解释您那一团糟的继承问题。

仅仅因为它听起来很酷而且您可以做到,并不意味着您应该这样做。我强烈建议使用功能组件,如果您需要共享功能,请使用 higher-order functions , 和/或 custom hooks .

最佳答案

我猜你不想替换 props 和 state,因为你可能需要一个公共(public)接口(interface)来让父类工作。所以你可以让你的父类通用,然后合并额外的 Prop /状态。

class MyComponent<P, S> extends React.Component<ParentProps & P, ParentState & S> {}
//                ^ Generic P is for child props, Generic S is for child state

使用示例:

type ParentProps = { a: number }
type ParentState = { b: number }
class MyComponent<P, S> extends React.Component<ParentProps & P, ParentState & S> {}
let parentComponent = <MyComponent a={1} />

type ChildProps = { c: number }
type ChildState = { d: number }
class ExtendedComponent extends MyComponent<ChildProps, ChildState> {}
let childComponent = <ExtendedComponent a={1} c={2} />

关于reactjs - 如何从继承类覆盖 React.Component 状态类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57420840/

相关文章:

javascript - Reactjs,当我删除元素时数组索引发生变化

node.js - 如何使用 sequelize-typescript 从源实例创建关联实例

typescript - AbortController 的 Typescript 类型是什么?

c# - 传入和返回自定义数据——接口(interface)是正确的方法吗?

c# - 根据 T 返回具有不同内容的 List<T>

javascript - ReactJs 子组件未通过 Props 更新

javascript - 使用 React useContext 和 useReducer 时出现 Typescript 错误

javascript - React JS setState(...) : Can only update a mounted or mounting component

javascript - 从函数返回 Observable

java - 泛型类定义中的可变长度类型参数