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

Sea*_*ker 2 javascript reactjs react-router

我正在使用React Router创建一个应用程序,它具有多个路由,包括Uploader上传视频的组件和观看视频的Videos组件。视频页面将一些评论存储为状态,我希望在整个打开的应用程序中保留这些评论。但是,React Router似乎导致每个组件都需要重新安装而不是重新渲染,每当我重新路由回该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>
    )
    }
}
Run Code Online (Sandbox Code Playgroud)

这是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>

            )


    }
}
Run Code Online (Sandbox Code Playgroud)

Jav*_*ian 5

我不能完全理解“何时Video多次加载组件”的意思,但是让我看看我是否可以回答您的问题。

如果您说的Video是在导航(更改路线)并返回至该组件时已卸载该组件并进行了挂载-导致丢失了所拥有Video组件的状态-这render方法的预期行为Route

让我解释一下React Router页面上的官方文档:当您使用组件(而不是下面的render或child)时,路由器使用React.createElement从给定的组件中创建一个新的React元素。这意味着,如果您向组件prop提供内联函数,则将在每个渲染中创建一个新组件。这将导致现有组件的卸载和新组件的安装,而不仅仅是更新现有组件。使用内联函数进行内联渲染时,请使用渲染或子项属性。

这意味着如果更改route它将卸载并重新安装,但是在更改道具时不会卸载并重新安装。请注意,文档中的声明“由于每次更改都会创建一个新组件 ”是指由于道具(而不是路线)的更改而导致的渲染。两者componentrender都将在导航时卸载,并在导航中装载,这是预期的(和期望的)行为。

  • 不要在路线更改与道具更改之间的安装/卸载之间混淆。官方文档试图声明`component`可以在prop更改上卸载/安装,但是`render`不能卸载prop更改上/安装。路由更改中的两个卸载/安装。官方文档中的“每个渲染”并不是指路线更改,而是道具的更改(触发了渲染)。 (2认同)