如何使用指向相同 URL 的 React-Router 重新渲染组件<Link>



为了简单起见,详细信息页面根据URL中的电影ID在装载时获取数据,该数据来自Route中的path='vie/:ID'。

它的子项名为"推荐",它会再次根据当前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}/>
}
}

推荐组件也基于当前电影获取数据,并生成指向另一部电影的另一个标记。

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>
</>
)
}
}

现在,当单击"推荐"组件中生成的链接时,如何触发父组件的另一个渲染?URL正在更改,但这不会像我想要的那样触发渲染。

更新:

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

这次我传入了一个唯一的键,它触发了页面的重新呈现。我以前试过这个,但我可能把语法搞砸了。

这篇文章让我走上了正确的方向:当点击同一个反应路由器链接多次时,强制重新安装组件

向页面添加键

如果你改变了路线,但你的页面没有得到它的";安装件";数据,则应该向页面添加一个键。这将导致您的页面重新发送并使用新id装载,然后再次获取数据。

你可以在这里阅读更多关于反应键

一个键告诉react这是一个特定的组件,这就是为什么你在列表中看到它们。通过更改页面上的键,您可以告诉react这是组件的新实例化,并且已经更改。这将导致重新装载。

类组件示例

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>
)
}
}

功能组件示例

const MyPage = (props) => {
React.useEffect(() => {
// this will fire each time the key changes
}, []);
return (
<div key={props.pageId}>
{/* component stuff */} 
</div>
)
}

您可以在您的推荐组件中添加另一个React生命周期方法,该方法在接收新道具时触发(UNSAFE_componentWillReceiveProps、componentDidUpdate、getDerivedStateFromProps(,如下所示:

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

您还可以将密钥添加到组件中(如果密钥发生更改,将强制其完全重新渲染(,如下所示:

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

你也可以使用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>
</>
);
};

注意:向组件添加密钥并完成其重新渲染不是最佳做法,如果可能的话,您应该使用组件的生命周期来避免

最新更新