React Router Link with params not reloading page with new data from componentDidMount and Redux axios data fetching

javascript reactjs router

577 观看

2回复

361 作者的声誉

I have this react + redux app

I have 1 Movie component with some movie data displayed on it which are fetched from API.

So at the bottom, i decided to add a Similar movies section with a couple of components to navigate to the new movie pages.

<div className="similar_movieS_container">
    { this.props.thisMovieIdDataSIMILAR.slice(0,4).map((movie,index)=>{
         return(

            <Link to={"/movie/"+movie.id} key={index}>

               <div className="similar_movie_container">
                 <div className="similar_movie_img_holder">
                   <img src={"http://image.tmdb.org/t/p/w185/"+movie.poster_path} className="similar_movie_img" alt=""/>
                    </div>
                  </div>
                </Link>
                )
            })
          }
 </div>

Now when I'm at a root route for instance /toprated and i click on a <Link to={"/movie/"+movie.id} key={index}> i get navigated to the particular route (e.g. /movie/234525 ) and everything works fine , but if I'm in a /movies/{some move ID } route and i click on some <Link to={"/movie/"+movie.id} key={index}> The route in the URL bar gets updated, but the page stays still, meaning nothing changes if I reload the page with the new route the new movieID data is displayed...

this is my App.js

   <BrowserRouter>
     <Switch>
        <Route  path='/' exact component={Home} />
        <Route  path='/discover' exact component={Discover} />
        <Route  path='/toprated' exact component={TopMovies} />
        <Route  path='/upcoming' exact component={Upcoming} />
        <Route  path='/movie/:movieId' exact component={()=><Movie/>} />
      </Switch>
    </BrowserRouter>

and the componentDdidMount of the Movie.jsx Component

...
componentDidMount() {
    window.scroll(0, 0);
    this.movieID = parseInt(window.location.href.split("/")[window.location.href.split("/").length-1]);
    this.props.getMovieInfo(this.movieID);
    this.props.getMovie_YOUTUBE(this.movieID);
    this.props.getMovie_SIMILAR(this.movieID);
  }
  ...

So how can i make a navigation to a new /movie/{movieID} FOMR a /movie/{movieID} ?

作者: Георги Димитранов 的来源 发布者: 2017 年 12 月 27 日

回应 2


0

1790 作者的声誉

When you navigate from a route to another instance of the same route, react-router uses the same component without mounting or un-mounting, re-using the same component with different props. So form a developer POV, you will see the component will be used but it's props will be updated.

What I can suggest is to extract your logic into a custom method on the component class and re-use it on componentDidMount and componentWillReceiveProps, which is called when the url of the same route changes.

class MyComponent extends React.Component {
  componentDidMount() {
    myCustomLogic();
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.params.movieId !== this.props.params.movieId) {
      myCustomLogic();
    }
  }
  myCustomLogic() {
    ...
  }
}
作者: Farzad YZ 发布者: 2017 年 12 月 27 日

0

120434 作者的声誉

The problem is in the way you have rendered the Movie Route, You seem to have mixed syntaxes of component and render props. You could either configure your Route as

<Route  path='/movie/:movieId' exact component={Movie} />

or

<Route  path='/movie/:movieId' exact render={(props)=><Movie  {...props}/>} />

make sure to pass the Router props to the component when using render props like it is shown in the above example or else the Router props won't be available to Movie component and it would behave inconsistently with the Router like changing the url but not actually navigating when clicking on Link inside it

Also when you navigate to the Same route the component isn't re-mounted but re-rendered. So you need to fetch the updated data in componentWillReceiveProps function:

componentWillReceiveProps(nextProps) {

    if(nextProps.match.params.movieId !== this.props.params.movieId) {
      window.scroll(0, 0);
      this.movieID = nextProps.match.params.movieId
      this.props.getMovieInfo(this.movieID);
      this.props.getMovie_YOUTUBE(this.movieID);
      this.props.getMovie_SIMILAR(this.movieID);
    }
}
作者: Shubham Khatri 发布者: 2017 年 12 月 27 日
32x32