Почему React Router заставляет мои компоненты перемонтировать, а не просто перерисовывать? - PullRequest
2 голосов
/ 21 сентября 2019

Я создаю приложение, использующее реагирующий маршрутизатор, с несколькими маршрутами, включая компонент Uploader, куда загружаются видео, и компонент Videos, где они просматриваются.На странице видео хранятся некоторые комментарии в виде состояния, которое я хочу оставить на странице в течение всего открытого приложения.Однако реагирующий маршрутизатор, кажется, заставляет каждый компонент перемонтировать, а не перерисовывать, в результате чего мое состояние сбрасывается до первоначальных пустых значений всякий раз, когда я перенаправляю обратно к компоненту 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>

            )


    }
}

1 Ответ

5 голосов
/ 21 сентября 2019

Я не совсем понимаю, что вы подразумеваете под "когда компонент Video загружен более одного раза", но позвольте мне посмотреть, смогу ли я ответить на ваш вопрос.

Если вы говорите, чтоVideo компонент демонтируется и монтируется, когда вы перемещаетесь (изменяете маршрут) назад и обратно к нему - что приводит к потере состояния Video компонента, который у вас был - что является ожидаемым поведением render метод Route.

Позвольте мне объяснить в отношении официальных документов на странице реагирующего маршрутизатора: Когда вы используете компонент (вместо рендера или дочерних элементов, ниже), маршрутизатор использует React.createElementсоздать новый элемент React из данного компонента.Это означает, что если вы предоставите встроенную функцию для компонента prop, вы будете создавать новый компонент при каждом рендеринге.Это приводит к размонтированию существующего компонента и монтированию нового компонента вместо простого обновления существующего компонента.При использовании встроенной функции для встроенного рендеринга используйте рендер или дочернюю опору ...

Это означает, что он будет размонтироваться и перемонтироваться, если вы измените маршрут , однакоон не будет демонтироваться и перемонтироваться при изменениях реквизита.Обратите внимание, что оператор в документах, где написано ", вы будете создавать новый компонент при каждом рендеринге ", относится к рендерингу из-за изменения реквизита, а не к маршруту.И component, и render будут размонтироваться при навигации и монтироваться при навигации, и это ожидаемое (и желаемое) поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...