为什么 React Router 导致我的组件重新挂载,而不仅仅是重新渲染?



我正在使用 react router 创建一个应用程序,其中包含几条路由,包括上传视频的Uploader组件和查看视频的Videos组件。视频页面将一些评论存储为状态,我想在整个应用程序打开期间将其保留在页面上。但是,反应路由器似乎导致每个组件重新挂载而不是重新渲染,导致每当我重新路由回Video组件时,我的状态都会重置为初始空值。我在Route组件中使用render方法而不是component方法,所以我不明白为什么会发生这种情况。有谁知道是什么原因造成的?

以下是发生路由的主要应用:

class App extends React.Component{
constructor(props){
super(props)
var fileNames
var files
var fileSelected
this.state={fileSelected:null}
}
getFileFromChild= (uploadedFiles)=> {
this.files = uploadedFiles
}
fileButtonClicked= (index)=> {
//extract file chosen by user based on button click
this.setState({fileSelected: this.files[0][index]})
}
render(){
//destructuring props in class component
const {user} = this.props;
return(
<Router>
<div className = "nav-bar">
<Nav/>
<Switch>
<Route path='/' exact render={()=> <HomePage />
}/> 
<Route path='/videos' render={()=> <Videos files= {this.files} fileSelected={this.state.fileSelected}/>
}/>
<Route path='/uploader' render={()=> <Uploader  passFile= {this.getFileFromChild} fileButtonClicked={this.fileButtonClicked}/>
} />
</Switch>

</div>
</Router>
)
}
}

这是存储我需要的状态的Videos组件:

class Videos extends React.Component{
constructor(props){
super(props)
this.videoRef = React.createRef();
}
// once DOM loads get video tag and reload it
componentDidUpdate(){
this.videoRef.current.load()
}
render(){
const {files, fileSelected}=this.props;
var src = (fileSelected) ? URL.createObjectURL(fileSelected): URL.createObjectURL(files[0][0])
return( 
<div>
<div className="ui one column centered grid">
<div className="one wide column"> {/*needs to be one wide here not just column for center to work*/}
<h3>Videos</h3>
</div>
</div>
<div className="ui grid">
<div className="ten wide column">
<video ref={this.videoRef} controls width="566" height="320">
<source src={src} id='video' type="video/mp4" />
Your browser does not support HTML5 video.
</video>
<CommentsSection/>
</div>
<div className="six wide column">
{files[1]}
</div>

</div>
</div>
)

}
}

我不完全明白你所说的"当Video组件加载多次时"是什么意思,但让我看看我是否可以回答你的问题。

如果您说当您导航(更改路线(离开并返回Video组件时,该组件被卸载并挂载 - 导致丢失您拥有的Video组件的状态 - 这是renderRoute方法的预期行为

让我解释一下反应路由器页面上的官方文档:

当您使用组件(而不是下面的渲染或子元素(时,路由器使用 React.createElement 从 给定组件。这意味着,如果您为 组件属性,您将在每次渲染时创建一个新组件。这 导致现有组件卸载和新组件 挂载,而不仅仅是更新现有组件。使用时 用于内联渲染的内联函数,使用渲染或 儿童道具...

这意味着:

  • 传递到render或 propcomponent组件将始终在路由更改时卸载并装载
  • 如果将内联组件传递到renderProp 中,它不会在每个渲染时卸载和重新挂载 - 它会"记住"内联函数并且不执行挂载/卸载
  • 如果您将内联组件传递到componentProp 中,它将在每个渲染上卸载并挂载 - 它将在每个渲染上重新创建内联组件,以便卸载组件的旧实例并挂载新创建的组件实例

要点:

  • component道具和render道具都会在导航离开时卸载,并在导航时装载,这是预期和期望的行为。
  • 您将内联组件传递到renderprop 中(例如<Route render={() => <HomePage />}(
  • 您将组件传递到component道具中(例如<Route component={HomePage} />(
  • 切勿将内联组件传递到component道具
  • 在您的情况下,您正确使用了render组件。您只是对路线更改与道具更改时的卸载和装载感到困惑

相关内容

最新更新