簡體   English   中英

React Component Inheritance 使用父方法和子方法

[英]React Component Inheritance to use parent method and child method

背景

我創建了一個功能齊全的組件。 組件有state和props,里面有很多方法。 根據操作系統(ios / android),我的組件應該以不同的方式工作。 所以我通過下面的if語句解決了這個問題。

if( platform.os == 'ios') {... } else {... }

問題是隨着代碼量的增加,可讀性出現問題,我決定為 IOS 和 Android 制作單獨的組件。 首先想到的是 inheritance,因為 ES6 和 Typescript 支持 Class。 概念圖是這樣的。

在此處輸入圖像描述

但是, React 不推薦 inheritance 所以我只是要把被 props 覆蓋的函數交給 SpeechIOS 組件的渲染 function 中的 Speech 組件。

代碼如下。

語音.tsx

type Props = {
  team: number,
  onSpeechResults: (result: string) => void
  ...
}
type States = {
  active: boolean;
  error: string;
  result: string;
  ...
};

export default class Speech extends Component<Props,States> {
  state = { ... };
  constructor(props: Props) {
    super(props);
    ...
  }

  // render
  render() {
    ...
    return (
      <ImageBackground source={require("../images/default-background.jpeg")} style={styles.full}>
        ...
      </ImageBackground>
    );
  }
  sendCommand = (code: number, speed: number, callback?: () => void) => { ... }
  getMatchedSpell = (spellWord: string): { code: number, speed: number } => { ... }
  onSpeechResults(e: Voice.Results) { ... };
  ...
}

SpeechIOS.tsx

import Speech from './Speech';

type Props = {}
type States = {}
export default class SpeechIOS extends Component<Props,States> {
  constructor(props: Props) {
    super(props);
    ...
  }

  // render
  render() {
    ...
    return ( <Speech team="1" onSpeechResults={this.onSpeechResults}></Speech> );
  }

  sayHello() {
    console.log("Hello!!");
  }

  // I want that Speech Component call this onSpeechResults function
  onSpeechResults(result: string) {
    this.setState({...});
    let temp = this.getMatchedSpell( ... ); // which is in Speech Component
    this.sendCommand( 10, 100 ... ); // which is in Speech Component
    this.sayHello(); // which is in SpeechIOS component only
    ... other things..
  };
}

問題。

如您所見, onSpeechResults Component 中的 onSpeechResults 使用 Speech Component 和 SpeechIOS Component 中的一些功能。

那么,如何解決這個問題呢? 我應該使用 Inheritance 嗎?

您應該定義一個定義共享道具和方法的頂級組件,並使用它們來呈現您的 ios 或 android 組件。 把道具和方法傳給孩子。 這是在反應中優於 inheritance 的組合物。 例子:

class Speech extends React.Component {

  state ={shared: 'state'}

  sharedMethod = () => {
    this.setState({blah: 'blah})
  }

  render() {
    const Root = Platform.select({
      ios: SpeechIOS,
      android: SpeechAndroid
    })

    return <Root onClick={this.sharedMethod}  shared={this.state.shared}/>
  }

}

或者,將任何通用邏輯分解到實用程序 function 中,例如SpeechUtil.ts ,一個包含此共享邏輯和每個實用程序 function 的全新文件,然后導出它們。 然后,每個組件分別導入它們。 這樣可以確保如果您更新該邏輯,它會影響兩個組件

你可以使用 React.createRef 來達到這個目的。 下面是一個示例代碼。

import Speech from './Speech';

type Props = {}
type States = {}
export default class SpeechIOS extends Component<Props, States> {
    constructor(props: Props) {
        super(props);
        this.speech = React.createRef();
    }

    // render
    render() {
        ...
        return (<Speech ref={this.speech} team="1" onSpeechResults={this.onSpeechResults}></Speech>);
    }

    sayHello() {
        console.log("Hello!!");
    }

    // I want that Speech Component call this onSpeechResults function
    onSpeechResults(result: string) {
        this.setState({ ...});
        let temp = this.speech.current.getMatchedSpell(... ); // which is in Speech Component
        this.sendCommand(10, 100 ... ); // which is in Speech Component
        this.sayHello(); // which is in SpeechIOS component only
        ...other things..
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM