網站搜尋

在 React Native 中使用 TypeScript 創建自訂組件


我決定將我的 ReactNative 專案轉換為 TypeScript。我對 TypeScript 還很陌生,並且發現很難解決這個與自訂元件和繼承有關的問題。以下是我的(簡化版)程式碼

import React, { Component } from "react";
import { Button, View } from "react-native";

interface IMyComponentProps extends React.Props<IMyComponentProps> {
  colWidth?: number;
}

class MyComponent extends Component<IMyComponentProps> {
  getProps() {
    return this.props;
  }
}

class MyButton extends MyComponent {
  render() {
    return (
      <View {...this.getProps()}>
        <Button title={this.props.title} onPress={this.props.onPress} />
      </View>
    );
  }
}

我在 MyButton 組件中的 ...this.getProps() 收到紅色底線。此外,this.props.title 和 this.props.onPress 也沒有被識別。

你能幫我定義這兩個類別所需要的類型嗎?

謝謝

答案#1

首先,你需要宣告 MyButton 擁有更具體的屬性,因此 MyComponent 必須被參數化:

class MyComponent<P extends IMyComponentProps> extends Component<P> {
  getProps() {
    return this.props
  }
}

然後正確地擴展 MyComponent 並聲明它的 props:

interface IMyButtonProps extends IMyComponentProps {
  colWidth?: number;
  title: string;
  onPress: () => void;
}


class MyButton extends MyComponent<IMyButtonProps> {
  render() {
    return (
      <View {...this.getProps()}>
        <Button title={this.props.title} onPress={this.props.onPress} />
      </View>
    );
  }
}

然後,除非你正在使用難以推理的 refs,不要擴展 React.Props。只需這樣聲明你的介面:

interface IMyComponentProps {
  colWidth?: number;
}
interface IMyButtonProps extends IMyComponentProps {
  title: string;
  onPress: () => void;
}

大家一起來!

我

mport React, { Component } from "react";
import { Button, View } from "react-native";

interface IMyComponentProps {
  colWidth?: number;
}

class MyComponent<P extends IMyComponentProps> extends Component<P> {
  getProps() {
    return this.props
  }
}

interface IMyButtonProps extends IMyComponentProps {
  title: string;
  onPress: () => void;
}

class MyButton extends MyComponent<IMyButtonProps> {
  render() {
    return (
      <View {...this.getProps()}>
        <Button title={this.props.title} onPress={this.props.onPress} />
      </View>
    );
  }
}