Warning: Functions are not valid as a React child HOC

2019 picture 2019 · Jan 21, 2019 · Viewed 9.2k times · Source

I'm writing an HOC in Reactjs. When I'm going to return class in WithErrorHandler HOC I get a warning in console said

"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." However, if I remove class, warning will be gone.

I am going to add click handler for Modal to enable it to close. Also, I am going to get message from error which I have passed as an argument of second function for show in Modal.

import React, { Component } from 'react';
import Modal from '../Modal'

const WithErrorHandler = WrappedComponent => ({ error, children }) => {

return(

  class extends Component {
state = {modalShow: false}   
modalToggle = ()=> {
this.setState(ModalShow: !!error.message)}
    render() {
      return (
        <WrappedComponent>
          {error && <Modal type={error.messageType} message={error.message} />}
          {children}
        </WrappedComponent>
      );
      }
    }

)  
};

const DivWithErrorHandling = WithErrorHandler(({children}) => {
  return children
})

class App extends Component {
    state ={error: null}
    someMethode = ()=> {
      const sampleError = {//an object with message key}
      this.setState(error: sampleError)
    }
    Render(){
        return (
          <DivWithErrorHandling error={this.state.error} >
            <h1>Component</h1>
            <button onClick={this.someMethode}>
               Toggle Error
            </button>
          </DivWithErrorHandling>

        )
    }

}

Answer

Ganapati V S picture Ganapati V S · Jan 21, 2019

Your HOC is accepting actual component & returning a children function(wrapper component) which again returns a class component.

Instead of that your HOC should accept actual component & return a new wrapped component.

This should probably fix your issue.

const WithErrorHandler = WrappedComponent => ({ error, children }) => {
  return(
    <WrappedComponent>
      {error && <Modal type={error.messageType} message={error.message} />}
      {children}
    </WrappedComponent>
  );
};