I am writing a very simple react component but I am getting a console error with everything I have tried.

In my main render:


render() {
  const subreddits = withFetch(new Subreddits({}));
  ...
  {subreddits}
}

Subreddits:

class Subreddits extends React.Component<Record<string, unknown>, any> {
  displayName: string;
  constructor(props: any) {
    super(props);
    this.displayName = "Subreddits";
  }

  public render() {
    const data = this.props.data?.[0];
    const options = data?.map((e) => ({
      name: e,
      value: e,
    }));

    return (
      <SelectSearch
        search={true}
        options={options}
        value={this.props.input.h}
        name="reddit select"
        placeholder="Select"
        onChange={async (handle: string) => {
        }}
      />
    );
  }
}

I modified fetch to be much simpler:

function withFetch(WrappedComponent) {
  return class extends React.Component {
    displayName: string;
    constructor(props) {
      super(props);
      this.displayName = "log";
    }

    componentDidMount() {
      console.log("Hello World!");
    }

    render() {
      return <WrappedComponent />;
    }
  };
}

export default withFetch;

Excuse the poor typescript at the moment. Here is the error I am getting:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
    in div (created by InputGroup)
    in InputGroup (created by App)
    in div (created by App)
    in div (created by App)
    in App (created by HotExportedApp)
    in AppContainer (created by HotExportedApp)
    in HotExportedApp

Ok I realize its saying it cannot render a function however I open up the debugger and it is not a function but an object. I try to invoke it like a function just to be sure and it is definitely not. That leaves the other option if you return a Component instead of <Component /> However, it seems fine to me. When I comment out {subreddits} the error goes away. What mistake am I making?

1

There are 1 best solutions below

2
On BEST ANSWER

The argument for your higher-order component is the class (or function) for the component that you want to wrap, not an instance of that component.

What you want to do is create a new component by applying the HOC to the wrapped/inner component. This should happen outside of render() because it should only happen once and not on every re-render.

  const FetchableSubreddits = withFetch(Subreddits);

Then inside your render you can use this like any other JSX component.

<FetchableSubreddits someProp={someValue} />