Skip to content
Advertisement

Functions are not valid as a React child. This may happen if you return a Component instead of from render. in react v6

Hello I’m new to react and got myself stuck here, my version is v6 and hence having a bit of a problem understanding, I’m following a tutorial from udemy

The error that occurred is – Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.

this is in my Home.js

class Dashboard extends Component {
  constructor(props) {
    super(props);   
    this.state = {
      child: props.nestedRoute,
      search: "",
    };
  }

  componentDidMount() {
    this.activeNav();
  }

  activeNav() {
    const pathname = window.location.pathname;
    const possibleRoutes = [
      { routes: "/dashboard", targetId: "home" },
      { routes: "/addProduct", targetId: "addProduct" },
      { routes: "/products", targetId: "products" },
      { routes: "/profile", targetId: "profile" },
    ];
    possibleRoutes.forEach(({ route, targetId }) => {
      window.jQuery(`#${targetId}`).removeClass("active");
      if (route === pathname) {
        window.jQuery(`#${targetId}`).addClass("active");
      }
    });
  }

  render() {
    const Child = this.state.child
    console.log(Child)
    const { user } = this.props.auth;

    return (
      <div id="content-wrapper" className="d-flex flex-column">
        <div id="content">
          <nav className="navbar navbar-expand navbar-light bg-white topbar mb-44 static-top shadow">        
            <ul className="navbar-nav ml-auto">
              <li className='nav-item dropdown no-arrow'>
                <Link
                  className="nav-link dropdown-toggle"
                  to="#"
                  id="userDropdown"
                  role="button"
                  data-toggle="dropdown"
                  aria-haspopup="true"
                  aria-expanded="false"
                >
                  <span className="mr-2 d-none d-lg-inline text-gray-600 small">
                    {user.name}
                  </span>
                  <Avatar size={40}>
                    {user.name && this.avatarText(user.name)}
                  </Avatar>
                </Link>

                <div
                  className="dropdown-menu dropdown-menu-right shadow animated--grow-in"
                  aria-labelledby="userDropdown"
                >
                  <Link className="dropdown-item" to="#">
                    <i className="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
                    Profile
                  </Link>
                  <Link className="dropdown-item" to="#">
                    <i className="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i>
                    Settings
                  </Link>
                  <Link className="dropdown-item" to="#">
                    <i className="fas fa-list fa-sm fa-fw mr-2 text-gray-400"></i>
                    Activity Log
                  </Link>
                  <div className="dropdown-divider"></div>
                  <Link
                    className="dropdown-item"
                    to="#"
                    onClick={this.logUserOut}
                  >
                    <i className="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
                    Logout
                  </Link>
                </div>
              </li>
            </ul>
          </nav>
          <Child {...this.props} search={this.state.search} />
        </div>
      </div>
    );
  }
}

Dashboard.propTypes = {
  auth: PropTypes.object.isRequired,
  logout: PropTypes.func.isRequired,
};

const mapStateToProps = (state) => ({
  auth: state.auth,
});

export default connect(mapStateToProps, { logout })(Dashboard);

my App.js looks like this

function App(props) {
  useEffect(() => {
    store.dispatch(setCurrentUser())
  }, [])

  return (
    <Provider store={store}>
      <Router>
        <Routes>
          <Route exact path="/" element={<Landing/>} />
          <Route exact path="/" element={<ProtectedRoute/>}>  
            <Route exact 
              path="/dashboard" 
              element={()=> (<Dashboard {...props} nestedRoute={Home} />)} 
            />
            <Route exact 
              path="/dashboard/addProduct" 
              element={()=> (<Dashboard {...props} nestedRoute={AddProduct} />)} 
            />
          </Route>
          <Route exact path="/register" element={<Register/>} />
          <Route exact path="/login" element={<Login/>} />
        </Routes>
      </Router>
    </Provider>

  );
}

Advertisement

Answer

In your react router use the render method.

<Route exact 
 path="/dashboard/addProduct" 
 render={()=> <Dashboard {...props} nestedRoute={AddProduct} />} 
/>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement