react router - passing props using route deletes all the other props values

Viewed 23

I have been working on a small project while learning full stack managment and a weird problem occurred.

import React, { useState } from "react";
import { Switch, Route } from "react-router-dom";
import AllMovies from "./AllMovies";
import AddMovie from "./AddMovie";
import EditMovie from "./EditMovie";
import "./App.css";

const Movies = (props) => {
  if (sessionStorage.getItem("login") === "false") props.history.push("/");

  const [searchInput, setSearch] = useState("");
  const [findMovie, setFindMovie] = useState("");
  return (
    <div className="movies">
      <h1>Movies</h1> <br />
      <button onClick={() => props.history.push(`${props.match.url}`)}>All Movies</button>
      <button onClick={() => props.history.push(`${props.match.url}/add-movie`)}>Add Movie</button>{" "}
      &nbsp; Find Movie:{" "}
      <input type="text" onChange={(e) => setSearch(e.target.value)} />
      &nbsp;
      <button onClick={() => setFindMovie(searchInput)}>Find</button>
      <Switch>
        <Route path={props.match.url} exact><AllMovies findMovieInput={findMovie} /></Route>
        <Route path={`${props.match.url}/add-movie`} component={AddMovie}></Route>
        <Route path={`${props.match.url}/edit-movie`} component={EditMovie}></Route>
      </Switch>
    </div>
  );
};

export default Movies;

when i log.console(props) inside the component AllMovies i get a single prop named findMovieInput. all the other props such as: match, history , location and staticContext dissapear. that will not allow me to use props.match.url or props.history.push("").

any advise how to overcome this?

is there another way to access those props using this method?

or am i just using it wrong?

1 Answers

Issue

You are rendering AllMovies as a child component of a Route so the route props are not passed/injected as props to the child component.

<Route path={props.match.url} exact>
  <AllMovies findMovieInput={findMovie} /> // <-- no route props passed!
</Route>

Solution

Use the Route component's render prop if you need to render a routed component (to receive route props) and pass along additional props like findMovieInput.

Example:

<Route
  path={props.match.url}
  exact
  render={props => (             // route props
    <AllMovies
      {...props}                 // passed through here
      findMovieInput={findMovie} // additional props
    />
  )}
/>

See:

Related