Home > Blockchain >  React-router-dom Render props isn't returning any component
React-router-dom Render props isn't returning any component

Time:12-08

I'm using react-router-dom version 6.0.2 here and the "Render" props isn't working, every time I got to the url mentioned in the Path of my Route tag it keeps throwing me this error - "Matched leaf route at location "/addRecipe" does not have an element. This means it will render an with a null value by default resulting in an "empty" page.". Can someone please help me with this issue

import './App.css';
import Home from './components/Home';
import AddRecipe from './components/AddRecipe';
import items from './data';
import React, { useState } from 'react';
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom';

const App = () => {
  const [itemsList, setItemsList] = useState(items)
  const addRecipe = (recipeToAdd) => {
    setItemsList(itemsList.concat([recipeToAdd]));
  }
  const removeItem = (itemToRemove) => {
    setItemsList(itemsList.filter(a => a!== itemToRemove))
  }
  return (
    <Router>
      <Routes>
        <Route path="/addRecipe" render={ ({history}) => {
          return (<AddRecipe onAddRecipe={(newRecipe) => {
            addRecipe(newRecipe);
            history.push('/');
          } }  />);
        } } />
        </Routes>
    </Router>
  );
}

export default App;

CodePudding user response:

In react-router-dom version 6, you should use element prop for this.

I suggest your read their document on upgrading from version 5 where they explain the changes.

For your problem, you should write something like this:

<Route 
   path="/addRecipe" 
   element={
      <AddRecipe 
         onAddRecipe={(newRecipe) => {
           addRecipe(newRecipe);
           history.push('/');
         } 
      />
   }  
 />

CodePudding user response:

The Route component API changed significantly from version 5 to version 6, instead of component and render props there is a singular element prop that is passed a JSX literal instead of a reference to a React component (via component) or a function (via render).

There is also no longer route props (history, location, and match) and they are accessible only via the React hooks. On top of this RRDv6 also no longer surfaces the history object directly, instead abstracting it behind a navigate function, accessible via the useNavigate hook. If the AddRecipe component is a function component it should just access navigate directly from the hook. If it unable to do so then the solution is to create a wrapper component that can, and then render the AddRecipe component with the corrected onAddRecipe callback.

Example:

const AddRecipeWrapper = ({ addRecipe }) => {
  const navigate = useNavigate();

  return (
    <AddRecipe
      onAddRecipe={(newRecipe) => {
        addRecipe(newRecipe);
        navigate('/');
      }}
    />
  );
};

...

const App = () => {
  const [itemsList, setItemsList] = useState(items);

  const addRecipe = (recipeToAdd) => {
    setItemsList(itemsList.concat([recipeToAdd]));
  };

  const removeItem = (itemToRemove) => {
    setItemsList(itemsList.filter(a => a !== itemToRemove))
  };

  return (
    <Router>
      <Routes>
        <Route
          path="/addRecipe"
          element={<AddRecipeWrapper addRecipe={addRecipe} />}
        />
      </Routes>
    </Router>
  );
};
  • Related