我有一个通过导入处理异步事件的组件,该导入处理父组件中的click事件。父组件侦听dom元素的单击并启动其this.handleMovieClick(event, 'movie name')
处理程序。
父级将closeVideo属性传递给异步加载的子级组件。在子组件中,它会侦听单击以关闭自身或在视频播放完毕时单击。它调用其this.handleVideoEnd()
,然后调用this.props.closeVideo
。
this.props.closeVideo
进入父级组件,并调用父级的this.handleCloseVideo()
。
我的问题是,当不再需要异步加载的组件时,该如何删除它?现在它位于DOM中。有没有一种方法可以强制删除组件?是否可以使用asyc呼叫componentWillUnmount
?
还是加载组件异步仅对代码拆分有用-根据需要加载所需的代码?这不是要从父级中删除组件吗?但是,React Router如何做到这一点?
父组件:
ParentComponent扩展了组件{
constructor(props) {
// bind event handlers
//用于保存对异步子加载组件的引用 this.state = { AnimatedFullScreenMovie:null, animationFullScreenMoviePath:null };
}
handleCloseVideo() {
this.setState({
AnimatedFullScreenMovie: null,
animatedFullScreenMoviePath: null
})
}
}
// handles loading the component async, sets the path to movie based on what clicked
handleViewMovieClick(event, name) {
event.preventDefault();
if (this.state.AnimatedFullScreenMovie === null) {
import('./../../../reusable/AnimatedFullScreenMovie').then(component =>
{
if (name === 'movie1') {
this.setState({
AnimatedFullScreenMovie: component,
animatedFullScreenMoviePath: "movie1.mp4"
});
} else {
this.setState({
AnimatedFullScreenMovie: component,
animatedFullScreenMoviePath: "movie2.mp4"
});
}
}
}
在父组件的render()
中:
render() {
// if the this.state.AnimatedFullScreenMovie has a component, render it
const showProfileVideo = () => {
if (typeof this.state.AnimatedFullScreenMovie !== undefined && this.state.AnimatedFullScreenMovie !== null) {
const AnimatedFullScreenMovie = this.state.AnimatedFullScreenMovie.default;
return (<AnimatedFullScreenMovie
videoSrc={this.state.animatedFullScreenMoviePath}
closeVideo={this.handleCloseVideo} // <-- pass the handleCloseVideo() as a prop to the async loaded child
/>);
} else {
return null;
}
}
return(
<section className="video-slider">
{ showProfileVideo() }
<div>
<p><a href="#" onClick={() => this.handleViewMovieClick(event, 'movie1')}>Watch the film</a></p>
</div>
<div>
<p><a href="#" onClick={() => this.handleViewMovieClick(event, 'movie2')}>Watch the film</a></p>
</div>
);
}
这是子异步组件:
export default class AnimatedFullScreenMovie extends Component {
constructor(props) {
super(props);
this.videoContainer, this.video;
this.playVideo = this.playVideo.bind(this);
this.handleVideoEnd = this.handleVideoEnd.bind(this);
this.handleClose = this.handleClose.bind(this);
}
componentDidMount() {
this.video.addEventListener('ended', this.handleVideoEnd);
}
playVideo() {
this.video.play();
}
handleVideoEnd() {
this.video.pause();
this.props.closeVideo; // <- launch the event handler in the parent to close the video by setting this.state.AnimatedFullScreenMovie to null
}
handleClose() {
this.handleVideoEnd()
}
componentWillUnmount() {
this.video.removeEventListener('ended', this.handleVideoEnd);
}
render() {
return (
<div id="animated-fullscreen-video-wrapper" ref={videoContainer => this.videoContainer = videoContainer}>
<h2 onClick={this.handleClose}>Close</h2>
<video src={this.props.videoSrc} ref={video => this.video = video} />
</div>
);
}
}
答案 0 :(得分:0)
我没有使用this.props.closeVideo
正确调用该函数。正确的方法是在异步子组件中使用this.props.closeVideo()
:
export default class AnimatedFullScreenMovie extends Component {
// previous code
handleVideoEnd() {
this.video.pause();
this.props.closeVideo(); // <- need to have the '()' chars in order to call
}
// remainder code
}