我正在使用react路由器创建一个应用,该应用具有多个路由,包括上传视频的Uploader
组件和观看视频的Videos
组件。视频页面将一些评论存储为状态,我希望在整个打开的应用程序中保留这些评论。但是,React路由器似乎正在导致重新安装每个组件,而不是重新渲染它们,每当我重新路由回Video
组件时,都会导致我的状态重置为初始空值。我在render
组件中使用的是component
方法,而不是Route
方法,所以我不明白为什么会这样。有谁知道是什么原因造成的?
这是路由发生的主要应用:
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>
)
}
}
答案 0 :(得分:5)
“ Video
组件被多次加载时,我不能完全理解您的意思,但是让我看看能否回答您的问题。
如果您说Video
组件在您导航(更改路线)并返回并返回时已卸载并已挂载-导致丢失了您拥有的Video
组件的状态- 是render
的{{1}}方法的预期行为。
让我解释一下React Router页面上的官方文档:当您使用组件(而不是下面的render或child)时,路由器会使用React.createElement从给定的组件创建一个新的React元素。这意味着,如果您向组件prop提供内联函数,则将在每个渲染中创建一个新组件。这将导致现有组件的卸载和新组件的安装,而不仅仅是更新现有组件。当使用内联函数进行内联渲染时,请使用渲染或子属性...
这意味着如果您更改路线会自动卸载并重新安装,但是不会在对道具进行更改时卸载并重新安装。请注意,文档中的声明“ 您将在每个渲染器中创建一个新组件”的声明是指由于道具的更改而导致的渲染,而不是路径。 Route
和component
都将在导航时卸载,并在导航中装载,这是预期的(和期望的)行为。