使用 typescript react 在构造函数中声明一个属性

IT技术 reactjs typescript
2021-05-08 20:58:15

从 Draft-js 文档中,可以(在原版 React 中,没有typescript)设置 Draft-js 环境,从而注意到该onChange属性可以直接在构造函数中声明:

import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';

class MyEditor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
  }
  render() {
    const {editorState} = this.state;
    return <Editor editorState={editorState} onChange={this.onChange} />;
  }
}

但是,当我尝试对 Typescript/React(下面的代码)执行相同操作时,出现此错误

错误 TS2339:类型“Main”上不存在属性“onChange”。

class Main extends React.Component<MainProps, MainState> {

    constructor(props) {
    super(props);
    this.state = { todos: [], editorState: EditorState.createEmpty() };
    this.onChange = (editorState) => this.setState({ editorState });
  }

我也尝试将onChange属性添加到props中

interface MainProps {
    model: Model;
    onChange: Function;
}

在typescript/react中声明这样的函数属性的合适方法是什么?

3个回答

试试这个:

class Main extends React.Component<MainProps, MainState> {
    constructor(props) {
        super(props);
        this.state = { todos: [], editorState: EditorState.createEmpty() };
        this.onChange = (editorState) => this.setState({ editorState });
    }

    onChange: (state: MainState) => void;

}

我还没有测试过,但我认为它应该可以工作。


编辑

是的,有一个我没有注意到的问题,应该是:

class Main extends React.Component<MainProps, MainState> {
    constructor(props) {
        super(props);

        this.state = { todos: [], editorState: EditorState.createEmpty() };
        this.onChange = (editorState) => this.setState({
            editorState: editorState
        } as MainState);
    }

    onChange: (state: MainState) => void;

}

类型的断言as MainState需要)如果todos(属性是不可选的,如果它是可选的todos?: any[]),那么就没有必要断言。

至于似乎与onChange定义重复的内容在 typescript docsMixins 部分对其进行了简短的解释,但在您的示例中是类中的定义:

onChange: (state: MainState) => void;

让编译器知道Main调用此方法的实例onChange接收 aMainState并返回void
但是这个方法的实现只有在ctor中创建实例时才会赋值:

this.onChange = (editorState) => this.setState({ editorState });

如果定义丢失,那么 ctor 中的赋值将产生编译错误:property 'onChange' does not exist on type 'Main'.

您可以像这样使用 handleChange 方法:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Editor, EditorState } from 'draft-js';

interface MyEditorProps {
}

class MyEditor extends React.Component<MyEditorProps, any> {
  constructor(props: MyEditorProps) {
    super(props);

    this.state = { editorState: EditorState.createEmpty() };
  }
  handleChange(e: EditorState) {
    this.setState({ editorState: e });
  }
  render() {
    return (
      <Editor editorState={this.state.editorState} onChange={e => this.handleChange(e)} />
    );
  }
}

ReactDOM.render(
  <MyEditor />,
  document.getElementById('editor'),
);

export { MyEditor }

或者,您可以像这样尝试:

private onChange = (editorState) => this.setState({ editorState } as MainState)

只是在类的主体中,您可以在其中定义其他类属性。我不知道你在运行哪个版本,但这段代码完全适用于ES2015TypeScript2.0.10