I am creating an app using react router, with several routes including a Uploader
ponent where videos are uploaded, and a Videos
ponent where they are viewed. The video page stores some ments as state, which i want to remain on the page throughout the app being open. However, react router seems to be causing each ponent to re-mount rather than re-render, causing my state to be reset to the intial empty values whenever i re-route back to the Video
ponent. I'm using the render
method rather than the ponent
method inside my Route
ponents, so i don't understand why this is happening. Does anyone know whats causing this?
Here is the main app where routing occurs:
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 ponent
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>
)
}
}
Here is the Videos
ponent where the state i need is stored:
class Videos extends React.Component{
constructor(props){
super(props)
this.videoRef = React.createRef();
}
// once DOM loads get video tag and reload it
ponentDidUpdate(){
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>
)
}
}
I am creating an app using react router, with several routes including a Uploader
ponent where videos are uploaded, and a Videos
ponent where they are viewed. The video page stores some ments as state, which i want to remain on the page throughout the app being open. However, react router seems to be causing each ponent to re-mount rather than re-render, causing my state to be reset to the intial empty values whenever i re-route back to the Video
ponent. I'm using the render
method rather than the ponent
method inside my Route
ponents, so i don't understand why this is happening. Does anyone know whats causing this?
Here is the main app where routing occurs:
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 ponent
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>
)
}
}
Here is the Videos
ponent where the state i need is stored:
class Videos extends React.Component{
constructor(props){
super(props)
this.videoRef = React.createRef();
}
// once DOM loads get video tag and reload it
ponentDidUpdate(){
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>
)
}
}
Share
Improve this question
edited Sep 20, 2019 at 23:01
Sean Barker
asked Sep 20, 2019 at 21:57
Sean BarkerSean Barker
3512 gold badges5 silver badges15 bronze badges
1 Answer
Reset to default 8I don't exactly get what you mean by "when the Video
ponent is loaded more than once" but let me see if I can answer your question.
If you're saying that the Video
ponent is unmounted and mounted when you navigate(change route) away and back to it - resulting in losing the state of the Video
ponent you had - that is the expected behaviour of the render
method of Route
.
Let me explain in regards to the official docs on the react router page:
When you use ponent (instead of render or children, below) the router uses React.createElement to create a new React element from the given ponent. That means if you provide an inline function to the ponent prop, you would create a new ponent every render. This results in the existing ponent unmounting and the new ponent mounting instead of just updating the existing ponent. When using an inline function for inline rendering, use the render or the children prop...
What this means is:
- ponent passed into either
render
orponent
prop will always unmount and mount on route change - if you pass an inline ponent into the
render
prop, it will not unmount and remount on every render - it will "remember" the inline function and not perform mount/unmount - if you passed an inline ponent into the
ponent
prop, it will unmount and mount on every render - it will re-create the inline ponent on every render so it performs the unmounting of the old instance of the ponent and mounting of the newly created instance of the ponent
Takeaways:
- both
ponent
andrender
props will unmount on navigating away, and mount on navigating in, and that is the expected and desired behaviour. - you pass an inline ponent into
render
prop (e.g<Route render={() => <HomePage />}
) - you pass a ponent into
ponent
prop (e.g<Route ponent={HomePage} />
) - never pass inline ponents into
ponent
prop - in your case, you're using the
render
ponent correctly. You just got confused with unmount and mounts on route change vs. prop change
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745196658a4616124.html
评论列表(0条)