Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么React Router会导致我的组件重新装载,而不仅仅是重新渲染?_Javascript_Reactjs_React Router - Fatal编程技术网

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

Javascript 为什么React Router会导致我的组件重新装载,而不仅仅是重新渲染?,javascript,reactjs,react-router,Javascript,Reactjs,React Router,我正在使用react router创建一个应用程序,其中包括一个上传视频的上传器组件和一个查看视频的组件。视频页面将一些评论存储为状态,我希望在整个应用程序打开的过程中保留在页面上。然而,react router似乎导致每个组件重新装载而不是重新渲染,导致每当我重新路由回视频组件时,我的状态被重置为初始空值。我在Route组件中使用的是render方法,而不是component方法,因此我不明白为什么会发生这种情况。有人知道这是什么原因吗 以下是路由发生的主要应用程序: class App ex

我正在使用react router创建一个应用程序,其中包括一个上传视频的
上传器
组件和一个查看视频的
组件。视频页面将一些评论存储为状态,我希望在整个应用程序打开的过程中保留在页面上。然而,react router似乎导致每个组件重新装载而不是重新渲染,导致每当我重新路由回
视频
组件时,我的状态被重置为初始空值。我在
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>
    )
    }
}

我不完全明白你所说的“当<代码>视频组件多次加载时”是什么意思,但让我看看是否可以回答你的问题

如果您说当您导航(更改路线)离开并返回
视频
组件时,
视频
组件被卸载和装载-导致丢失您拥有的
视频
组件的状态-这
路线
渲染
方法的预期行为

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


这意味着,如果你改变路线,它将卸载和重新装载,但是它不会卸载和重新装载道具。请注意,文档中的语句“每次渲染时您将创建一个新组件”指的是由于道具的更改而进行的渲染,而不是路线。
组件
渲染
在导航离开时卸载,在导航进入时装载,这是预期的(和期望的)行为。

是的,这就是我的意思。但是,我在这里没有使用
组件
,我使用的是
渲染
,所以我肯定不应该看到这种行为?不要混淆在路线更改和道具更改之间安装/卸载。官方文档试图说明
组件
在道具更改时卸载/装载,但
渲染
不会卸载/装载道具更改。两个卸载/装载都在路线更改时进行。官方文档中的“每次渲染”并不是指路线更改,而是指道具(触发渲染)的更改。此外,如果这回答了您的问题,您应该接受答案。
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>

            )


    }
}