indiehjaerta
indiehjaerta

Reputation: 341

Problem using Render instead of Component in React

I get this error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports

When clicking this link:

<li><NavLink activeClassName="active" to={{pathname: '/add-new'}}>Add new Recipe</NavLink>{' '} </li>

My route looks like this:

<PrivateRoute 
  exact 
  path='/add-new' 
  render={(props) => 
    <NewRecipe 
      {...props} 
      addRecipe={this.addRecipe}/>
  } 
  authenticated={authenticated} 
/>

PrivateRoute.js looks like this:

import React from "react";
import { Route, Redirect } from "react-router-dom";

export default function PrivateRoute({
  component: Component,
  authenticated,
  ...rest
}) {
  console.log(...rest);
  return (
    <Route
      {...rest}
      render={props =>
        authenticated === true ? (
          <Component {...props} {...rest} />
        ) : (
          <Redirect to="/login" />
        )
      }
    />
  );
}

Error occurs since I switched from Component={NewRecipe} to Render={...} since I need to pass a function.

Upvotes: 0

Views: 78

Answers (1)

Sasha
Sasha

Reputation: 5944

PrivateRoute skips render props (instead of call it), fix might be something like this (notice render() logic):

export default function PrivateRoute({
  component: Component,
  authenticated,
  render,
  ...rest
}) {
return (
    <Route
      {...rest}
      render={props =>
        authenticated === true ? (
          render ? render(props) : <Component {...props} {...rest} />
        ) : (
          <Redirect to="/login" />
        )
      }
    />
  );

It's overcomplex a bit, but I hope can help you understand the idea on how render prop might be caught.

Other solution is to change /add-new to be passed as a component:

  <PrivateRoute 
    exact 
    path='/add-new' 
    addRecipe={this.addRecipe}
    component={NewRecipe}
    authenticated={authenticated} 
  />

Upvotes: 1

Related Questions