ReactJS : Higher Order Component

Higher-order Component (HOC) adalah teknik untuk bikin komponen ReactJS baru dari komponen yang udah ada. Jadi kita bisa bikin komponen baru yang punya fitur atau fungsi tambahan dengan cara komposisi yaitu satu atau lebih komponen digabung & dibungkus komponen lain.

Kalo di bahasa OOP, ini cocok sama prinsip: Favor composition over inheritance

Misalnya kita punya komponen A & B. Kita bisa pake HOC untuk bikin komponen baru C yang isinya A & B plus fitur-fitur & komponen/elemen DOM yang lain. Jadi komponen C kurang lebih bisa digambarin kayak begini. Dua komponen yang lain tetep bisa dipake sendirian:

Contoh implementasi HOC antara lain di React-Redux, di mana kalo kita mau bikin komponen yang bisa merespon update di Store & kirim objek Action kita tulis kode begini:

import { connect } from 'react-redux';

export const MyComponent = (props) => ( // ...dsb );

//HOC
export default connect()(MyComponent);

Komponen MyComponent otomatis jadi subscriber & bisa dipatch action lewat this.props.dispatch().

Dalam demo di bawah ini saya ubah kode dari artikel Controlled & Uncontrolled Component sebelumnya.

See the Pen ReactJS: Higher-order Component by Anggie Bratadinata (@masputih) on CodePen.

Di sini saya buat contoh dua macam HOC, yang satu bikin functional / stateless component & yang satu lagi bikin stateful component (pake class).

Komponen dasarnya (base component) adalah text-input:

const MyInput = props => (
  <input
    disabled={props.disabled}
    type="text"
    className="input"
    placeholder={props.inputPlaceholder}
    value={props.inputValue}
    onChange={props.inputOnChange}
  />
);

Stateless HOC

HOC yang pertama cuman ngasih tambahan label & struktur DOM yang cocok untuk Bulma CSS Framework.

const WithLabel = Component => {
  return props => (
    <div className="field">
      <label className="label">{props.label}</label>
      <div className="control">
        <Component {...props} />
      </div>
    </div>
  );
};

Baris ini:

<Component {...props} />

Artinya, kirim semua props yang diset di komponen parent. Buat yg belum tau, itu {...} namanya Spread Operator.

Untuk pake hasil HOC ini, saya bikin konstanta namanya InputWithLabel.

const InputWithLabel = WithLabel(MyInput);

Terus saya pake di MyForm.render():

render() {
  return (
    <form>

      <InputWithLabel           
        label="Enter Name" 
        inputOnChange={this.handleNameChange}
        inputValue={this.state.name}
        inputPlaceholder="Enter name here"/>

      //...dst
    </form>
  );
}

Semua props dari InputWithLabel dikirim juga ke MyInput kayak begini:

Stateful HOC

HOC yang kedua adalah adalah input yang hanya bisa dipake kalo kondisinya “aktif” / “enabled“. Kondisi ini diatur pake checkbox.

Di sini saya butuh State, jadi HOC-nya harus bikin objek dari kelas React.Component.

const ToggleAble = Component =>{
  return class extends React.Component{
    constructor(props){
      super(props);
      this.state = {
        enabled: false
      }
    }
    toggleComponent(e){      
      this.setState({
        enabled: e.target.checked
      })
    }
    render(){
      const props = this.props;
      const enabled = this.state.enabled;
      return (
        <div className="field">
          <div className="control">
            <input type="checkbox" 
               onChange={this.toggleComponent.bind(this)} /> {props.checkboxLabel}
            <Component disabled={!enabled} {...props} />
          </div>
        </div>
      )
    }
  }
}

Terus saya bikin konstanta:

const ToggleAbleInput = ToggleAble(MyInput);

Pake di MyForm.render():

render() {
  return (
    <form>

      <InputWithLabel           
        label="Enter Name" 
        inputOnChange={this.handleNameChange}
        inputValue={this.state.name}
        inputPlaceholder="Enter name here"/>

      <ToggleAbleInput 
          checkboxLabel="Aktifin input di bawah" 
          inputOnChange={this.handleNameChange}
          inputValue={this.state.name}
          inputPlaceholder="Cek dulu checkbox di atas"/>

      //...dst
    </form>
  );
}

Penutup

Sekian tutorialnya. Kalo mau silakan demo di atas di-fork & dicoba-coba sendiri di Codepen.

Info lebih lanjut bisa dibaca di sini: ReactJS.org : HOC

Also in this category ...