简体   繁体   English

如何使用 React-Router 重新渲染组件<Link>指向同一个网址

[英]How to re-render a component with React-Router <Link> pointing to the same URL

To keep it simple, the detail page fetches data on mount based on the movie ID in the URL, this coming from path='movie/:id' in the Route.为简单起见,详细信息页面根据 URL 中的电影 ID 获取挂载数据,这来自路径中的 path='movie/:id'。

It's child is called Recommended, which shows you recommended movies based again on the current URL.它的子项称为推荐,它再次根据当前 URL 向您显示推荐的电影。

class MovieDetailPage extends React.Component {

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



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

The Recommended component fetches data based on the current movie as well and generates another tag pointing to another movie.推荐组件也根据当前电影获取数据,并生成指向另一部电影的另一个标签。

class Recommended extends React.Component {

    componentDidMount() {
        this.props.getRecommended(this.props.id)
    }

    render() {
        return (
            <>
            <Category title={'Recommended'}></Category>
            <div className="movies">
                {   
                    this.props.recommended.map((movie) => {
                        return (
                            <Link key={movie.id} to={`movie/${movie.id}`} className="movies__item">
                                <img
                                    key={movie.id}
                                    src={`https://image.tmdb.org/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 component when clicking the Link generated in the Recommended component?现在如何在单击“推荐”组件中生成的链接时触发父组件的另一个渲染? The URL is changing but this won't trigger a render like I intent to do. URL 正在更改,但这不会像我打算做的那样触发渲染。

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 component when click on the same react router Link multiple times这篇文章让我朝着正确的方向前进: 多次单击同一个反应路由器链接时强制重新安装组件

Add a key to the page给页面添加一个key

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.这将导致您的页面重新渲染并使用新 ID 挂载并再次获取数据。

You can read more about react keys here您可以在此处阅读有关反应键的更多信息

A key tells react that this is a particular component, this is why you see them in on lists.一个键告诉 react 这是一个特定的组件,这就是为什么你会在列表中看到它们。 By changing the key on your page you tell react that this is a new instantiation of the component and has changed.通过更改页面上的键,您可以告诉 react 这是组件的新实例并且已经更改。 This will cause a remount.这将导致重新装载。

Class component example类组件示例

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

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

Functional component example功能组件示例

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

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

You can add another React lifecycle method that triggers on receiving new props (UNSAFE_componentWillReceiveProps, componentDidUpdate, getDerivedStateFromProps) in your Recommended component like this:您可以添加另一个 React 生命周期方法,该方法在您的推荐组件中接收新道具(UNSAFE_componentWillReceiveProps、componentDidUpdate、getDerivedStateFromProps)时触发,如下所示:

UNSAFE_componentWillReceiveProps(nextProps) {
  if (nextProps.id !== this.props.id) {
    nextProps.getRecommended(nextProps.id);
  };
}

You can also add key to your component (which forces it to re-render completely if key changed) like this:您还可以向组件添加密钥(如果密钥更改,则强制它完全重新渲染),如下所示:

<Recommended 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:你还可以使用 React Hooks 通过 useEffect 更轻松地处理这个问题:

const Recommended = (props) => {
  const { id, getRecommended, recommended } = props;
  useEffect(() => {
    id && getRecommended(id);
  }, [id]);

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

Note : adding key to component and complete its re-render is not best practice and you should be using Component's lifecycles to avoid it if possible注意:向组件添加密钥并完成其重新渲染不是最佳实践,如果可能,您应该使用组件的生命周期来避免它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM