reactjstogglebuttonhigh-order-component

How to avoid repeating code within togglers using HOC in react


I tried to implement an HOC in react in order to avoid code repetition, so I created 2 buttons to toggle the components state, following my code:

Clickbtn.js:

export default class Card extends Component {
  constructor() {
    super()
    this.state = {
      starred: true
    }
    this.toggleStar = this.toggleStar.bind(this);
  }
  toggleStar() {
    this.setState({ starred: !this.state.starred })
  }
  render() {
    const { starred } = this.state;
    return (
      <div>
        <h3>My sweet Repo</h3>
        <p>My sweet description</p>
        <button onClick={this.toggleStar}>{starred ? "OK" : "NOK"}</button>
      </div>
    )
  }
}

Hideshow.js:

import React, { Component } from 'react';

class Hideshow extends Component {
  constructor(props) {
    super(props);
    this.toggleShow = this.toggleShow.bind(this);
    this.state = {
      show: true
    };
  }
  
  toggleShow() {
    this.setState({ show: !this.state.show })
  }

  render() {
    const { show } = this.state;
    return (
      <div>
        <button onClick={this.toggleShow}>Menu</button>
        { show && <nav style={{ listStyleType: 'none' }}>
         <a href="/#">Home</a>
         <a href="/#">Profile</a>
         <a href="/#">About</a>
        </nav>}
      </div>
    )
  }
}

HOC.js:

function withToggler(Component) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
         on: true
      };
    }

    toggler = () => {
      this.setState({ on: !this.state.on });
    };

    render() {
      const { on } = this.state;
      const { component , ...props } = this.props;
      return (
        <Component
          on={on}
          toggler={this.toggler}
          {...props}
        />
      );
    }
  };
}

export default withToggler;

However, I tried several ways to implement the HOC in my Clickbtn.js and Hideshow.js but I didn't yet figure out how to do that. I know that this part of the code is repeated:

 constructor() {
    super()
    this.state = {
      starred: true
    }
    this.toggleStar = this.toggleStar.bind(this);
  }
  toggleStar() {
    this.setState({ starred: !this.state.starred })
  }

So my question is how to implement HOC to avoid this code repetition?


Solution

  • You can use on and toggler props from withToggler to avoid repetition.

    class Card extends Component {
      constructor() {
        super()
    
        this.toggleStar = this.props.toggler;
      }
    
      render() {
        const starred  = this.props.on;
        return ( <
          div >
          <
          h3 > My sweet Repo < /h3> <
          p > My sweet description < /p> <
          button onClick = {
            this.toggleStar
          } > {
            starred ? "OK" : "NOK"
          } < /button> <
          /div>
        )
      }
    }