React Router Dynamic Route: Invalid URL

Viewed 309

1) In React Router

<Route path={"/movie/:id"} component={ResultPage} />

2) Search Component

<div className="results">
  {data.map((movie) => (
    <Result
      poster_path={movie.poster_path}
      alt={movie.title}
      key={movie.id}
      id={movie.id}
      title={movie.title}
      overview={movie.overview}
      release_date={movie.release_date}
      genre_ids={movie.genre_ids}
    />
  ))}
</div>;

enter image description here

3) Result Component

export default function Result(props) {
  const { poster_path: poster, alt, title } = props;

  return (
    <div className="result">
      <Link
        to={{
          pathname: `/movie/${title}`,
          state: { ...props },
        }}
      >
        <img
          src={
            poster
              ? `https://image.tmdb.org/t/p/original/${poster}`
              : "https://www.genius100visions.com/wp-content/uploads/2017/09/placeholder-vertical.jpg"
          }
          alt={alt}
        />
      </Link>
    </div>
  );
}

4) ResultPage component

You can see the URL is now http://disnyplus.plus/movie/avengers-endgame however if you open a new tab and copy/paste the same URL the page will error because it doesn't have all the data is my guess, since it got it from the props from the Search -> Click Result -> ResultPage flow.

Is there another approach to achieve this or is a side-effect of using dynamic pages and passing props to it?

enter image description here

2 Answers

As you can see, the data that are stored in the props.location.state are not accessible when users refresh the page or visit the page without redirecting from the search page. As a result, it would not be a good practice.

I would recommend keeping the title ( or id ) of the movie in the URL ( as you have already done), and then receive the desired data in the ResultPage component based on the title or id of the movie. You can take advantage of React lifecycles to send a request in order to fetch the data. You can read more about the best way of fetching data in class and functional components here in the documnetation.

The other solution that can solve your issue, but I would not recommend, is storing the data in Cookies or Local Storage and make them accessible on reloads.

So this is the problem with client-side routing, basically before you can hit your url, in this case http://disnyplus.plus/movie/avengers-endgame, your browser makes a request to the server and since there is no server-routing present, the page will result in an error. It does so because not all javascript necessary to get the movie has been performed. React let's you open pages on your website without refreshing by performing some javascript.

One of the possible solutions I could recommend is using HashRouter instead, your urls would look something like this http://disnyplus.plus/#/movie/avengers-endgame.

Hash routes ignore the part of the url after the hash so they don't ask server for the specific url, but what they do is call the index page first and then render what they are supposed to accordingly.

If you are curious, I think this answer really nailed the server/client/hybrid side routing even though the question doesn't match yours. I think you could learn something from it.

React-router urls

Related