1

I am trying to create an HOC example in React+Typescript, but my code doesn't work.

codesandbox

This is the HOC component:

Hello.jsx

import * as React from "react";

export interface Props {
  name: string;
  itemClicked: () => void;
}

interface State {
  inc: number;
}

export const makeHello = <P extends Props>(Component: React.ComponentType<P>) =>
  class Hello extends React.Component<Props, State> {
    constructor(props: Props) {
      super(props);

      this.state = {
        inc: 0
      };
    }

    itemClicked = () => {
      this.setState({ inc: inc + 1 }, () => {
        console.log("itemClicked");
      });
    };

    render() {
      return (
        <Component itemClicked={this.itemClicked} {...this.props}>
          Inc state is: {this.state.inc}!
        </Component>
      );
    }
  };

export default makeHello;

And component ChildHello:

import * as React from "react";
import { Props } from "./Hello";
import { makeHello } from "./Hello";

export class ChildHello extends React.Component<Props, {}> {
  static defaultProps = {
    className: ""
  };

  constructor(props: Props) {
    super(props);
  }

  render() {
    return <div onClick={this.props.itemClicked}>Child component</div>;
  }
}

export default makeHello(ChildHello);

I don't get any error, but method itemClicked in Hello.jsx is not triggered when I click div element in ChildHello.tsx.

1 Answer 1

3

Looks like you made an import/export mistake.

You were importing the named class from the ChildHello instead of the HOC wrapped default export.

import * as React from "react";
import { Props } from "./Hello";
import makeHello from "./Hello";

// In index.tsx import { ChildHello } refers to this, not the default export below
export class ChildHello extends React.Component<Props, {}> {
  static defaultProps = {
    className: ""
  };

  constructor(props) {
    super(props);
  }

  render() {
    console.log(this);
    return <div onClick={this.props.itemClicked}>Child component</div>;
  }
}

export default makeHello(ChildHello);

In your index.tsx make sure you remove the named import

import ChildHello from "./ChildHello";

Then in your Hello.tsx update the itemClicked method, because it's erroring out

// UPDATED added "this.state" to inc
this.setState({ inc: this.state.inc + 1 }, () => {
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.