最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to re-render a component with React-Router <Link> pointing to the same URL - Stack Overflow

programmeradmin1浏览0评论

To keep it simple, the detail page fetches data on mount based on the movie ID in the URL, this ing from path='movie/:id' in the Route.

It's child is called Remended, which shows you remended movies based again on the current URL.

class MovieDetailPage extends React.Component {

    // Fetch movies and cast based on the ID in the url
    ponentDidMount() {
        this.props.getMovieDetails(this.props.match.params.id)
        this.props.getMovieCast(this.props.match.params.id)
    }



    render() {            
        <div>
          Movies here
        </div>
        <Remended id={this.props.match.params.id}/>
    }
}

The Remended ponent fetches data based on the current movie as well and generates another tag pointing to another movie.

class Remended extends React.Component {

    ponentDidMount() {
        this.props.getRemended(this.props.id)
    }

    render() {
        return (
            <>
            <Category title={'Remended'}></Category>
            <div className="movies">
                {   
                    this.props.remended.map((movie) => {
                        return (
                            <Link key={movie.id} to={`movie/${movie.id}`} className="movies__item">
                                <img
                                    key={movie.id}
                                    src={`${movie.poster_path}`} 
                                    className="movies__item-img"
                                    alt={`A poster of ${movie.title}`}
                                >
                                </img>
                            </Link>
                        )                      
                    })
                }
            </div>
            </>
        )
    }
}

Now how can I trigger another render of the parent ponent when clicking the Link generated in the Remended ponent? The URL is changing but this won't trigger a render like I intent to do.

UPDATE:

<Route 
  path="/movie/:id" 
  render={(props) => (
  <MovieDetailPage key={props.match.params.id} 
  {...props} 
  )}
/>

I passed in a unique key this time that triggered the re-render of the page. I tried this before but I might've screwed up the syntax.

This post got me in the right direction: Force remount ponent when click on the same react router Link multiple times

To keep it simple, the detail page fetches data on mount based on the movie ID in the URL, this ing from path='movie/:id' in the Route.

It's child is called Remended, which shows you remended movies based again on the current URL.

class MovieDetailPage extends React.Component {

    // Fetch movies and cast based on the ID in the url
    ponentDidMount() {
        this.props.getMovieDetails(this.props.match.params.id)
        this.props.getMovieCast(this.props.match.params.id)
    }



    render() {            
        <div>
          Movies here
        </div>
        <Remended id={this.props.match.params.id}/>
    }
}

The Remended ponent fetches data based on the current movie as well and generates another tag pointing to another movie.

class Remended extends React.Component {

    ponentDidMount() {
        this.props.getRemended(this.props.id)
    }

    render() {
        return (
            <>
            <Category title={'Remended'}></Category>
            <div className="movies">
                {   
                    this.props.remended.map((movie) => {
                        return (
                            <Link key={movie.id} to={`movie/${movie.id}`} className="movies__item">
                                <img
                                    key={movie.id}
                                    src={`https://image.tmdb/t/p/w342${movie.poster_path}`} 
                                    className="movies__item-img"
                                    alt={`A poster of ${movie.title}`}
                                >
                                </img>
                            </Link>
                        )                      
                    })
                }
            </div>
            </>
        )
    }
}

Now how can I trigger another render of the parent ponent when clicking the Link generated in the Remended ponent? The URL is changing but this won't trigger a render like I intent to do.

UPDATE:

<Route 
  path="/movie/:id" 
  render={(props) => (
  <MovieDetailPage key={props.match.params.id} 
  {...props} 
  )}
/>

I passed in a unique key this time that triggered the re-render of the page. I tried this before but I might've screwed up the syntax.

This post got me in the right direction: Force remount ponent when click on the same react router Link multiple times

Share Improve this question edited Feb 27, 2020 at 0:52 Richard V asked Feb 26, 2020 at 14:56 Richard VRichard V 311 silver badge4 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Add a key to the page

If you change route but your page is not getting its "mount" data then you should add a key to the page. This will cause your page to rerender and mount with the new id and get the data again.

You can read more about react keys here

A key tells react that this is a particular ponent, this is why you see them in on lists. By changing the key on your page you tell react that this is a new instantiation of the ponent and has changed. This will cause a remount.

Class ponent example

class MyPage extends React.Component {
    ponentDidMound() {
      // this will fire each time the key changes since it triggers a mount
    }

    render() {
        return (
            <div key={props.pageId}>
               {/* ponent stuff */} 
            </div>
        )
    }
}

Functional ponent example

const MyPage = (props) => {
    React.useEffect(() => {
      // this will fire each time the key changes
    }, []);

    return (
        <div key={props.pageId}>
           {/* ponent stuff */} 
        </div>
    )
}

You can add another React lifecycle method that triggers on receiving new props (UNSAFE_ponentWillReceiveProps, ponentDidUpdate, getDerivedStateFromProps) in your Remended ponent like this:

UNSAFE_ponentWillReceiveProps(nextProps) {
  if (nextProps.id !== this.props.id) {
    nextProps.getRemended(nextProps.id);
  };
}

You can also add key to your ponent (which forces it to re-render pletely if key changed) like this:

<Remended key={this.props.match.params.id} id={this.props.match.params.id}/>

You can also use React Hooks to handle this more easily with useEffect:

const Remended = (props) => {
  const { id, getRemended, remended } = props;
  useEffect(() => {
    id && getRemended(id);
  }, [id]);

  return (
    <>
      <Category title={'Remended'}></Category>
      <div className="movies">
        {remended.map((movie) => {
          return (
            <Link key={movie.id} to={`movie/${movie.id}`} className="movies__item">
              <img
                key={movie.id}
                src={`https://image.tmdb/t/p/w342${movie.poster_path}`}
                className="movies__item-img"
                alt={`A poster of ${movie.title}`}
              ></img>
            </Link>
          );
        })}
      </div>
    </>
  );
};

Note: adding key to ponent and plete its re-render is not best practice and you should be using Component's lifecycles to avoid it if possible

发布评论

评论列表(0)

  1. 暂无评论