Вход

Просмотр полной версии : React Router - re-render компонента при смене url


smegol
20.09.2018, 13:07
Добрый день,

Делаю тренировочный проект на React с использованием библиотек React Redux и React Router DOM.

Код для примера такой:


<Switch>
<Route exact path='/' component={ MovieList }/>
<Route path='/genre/:genre' component={ MovieList }/>
<Route path='/login' component={ AuthForm }/>
</Switch>

<Nav>
// При переходе с URL '/genre/:genre' на '/' re-render не происходит потому что компонент не меняется у обоих Route - <MovieList />
<Link to="/"> Список фильмов </Link>
// При нажатии на ссылку re-render происходит потому что меняется store при onClick
<Link to="/genre/:genre" onClick={ this.props.movieGenre.bind(this) }> Список фильмов по жанру </Link>
// При нажатии на ссылку re-render происходит потому что в "Route" меняется компонент с <MovieList /> на <AuthForm />
<Link to="/login"> Авторизация </Link>
</Nav>


Подскажите пожалуйста может ли React Router делать ререндер одного и того же компонента при смене url?

Пример http://kino.ua-ix.biz/genre/Фентези (http://kino.ua-ix.biz/genre/%D0%A4%D1%8D%D0%BD%D1%82%D0%B5%D0%B7%D0%B8) если нажать на вкладку Список фильмов - компонент <MovieList /> не обновится - останутся фильмы "Фентези"

Царь Леонид
20.09.2018, 15:35
Это можно сделать миллион и одним способом, вопрос в том, зачем надо делать ререндер компонента. Один из способов проверять в shouldComponentUpdate текущие пропсы из роутера и те, которые приходят

smegol
20.09.2018, 17:11
Это можно сделать миллион и одним способом, вопрос в том, зачем надо делать ререндер компонента. Один из способов проверять в shouldComponentUpdate текущие пропсы из роутера и те, которые приходят

Спасибо! Так работает - просто если бы такое умел делать роутер - как с компонентом <AuthForm /> - было бы меньше кода.


shouldComponentUpdate(nextProps){
if(nextProps.location.pathname != this.props.location.pathname && nextProps.location.pathname == '/'){
this.props.movieList(0);
return nextProps;
} else {
return nextProps;
}
}

Царь Леонид
21.09.2018, 18:48
У тебя в коде всегда будет происходить перерендер, это неправильное поведение. shouldComponentUpdate должен возвращать или true или false, он у тебя все время объект возвращает, а объект == true.

smegol
22.09.2018, 23:41
У тебя в коде всегда будет происходить перерендер, это неправильное поведение. shouldComponentUpdate должен возвращать или true или false, он у тебя все время объект возвращает, а объект == true.

Мне перерендер этого компонента нужен всегда - т.к. при смене url должны подтянутся фильмы из БД которые соответствуют этому url.
Или тут что то не так?

Царь Леонид
23.09.2018, 10:55
Вообще-то да, не так. Это должно работать следующим образом - пришли новые данные -> обновили данные в хранилище (redux, mobx или даже просто в стейте компонента) -> произошел ререндер. Излишний перерендер - это явление с которым все борются, а у вас в коде это паттерн.

smegol
24.09.2018, 18:15
Вообще-то да, не так. Это должно работать следующим образом - пришли новые данные -> обновили данные в хранилище (redux, mobx или даже просто в стейте компонента) -> произошел ререндер. Излишний перерендер - это явление с которым все борются, а у вас в коде это паттерн.

Действительно с кодом у меня что то не так, я сделал console.log() в функции render() - она запускается несколько раз даже без shouldComponentUpdate(nextProps). Буду разбираться почему так происходит...

Царь Леонид
24.09.2018, 18:32
Если есть желание и возможность, сделай фиддл https://codesandbox.io/s/new я гляну

smegol
24.09.2018, 20:52
Если есть желание и возможность, сделай фиддл https://codesandbox.io/s/new я гляну

Буду рад если подскажите в каком направлении двигаться: https://codesandbox.io/s/lxlwv7x47l компонент со списком фильмов <MovieList>, роутинг в <Main>

smegol
29.09.2018, 23:58
Понял один нюанс shouldComponentUpdate - отключает обновление компонента если возвращает false.
Мне нужно было сделать так чтобы компонент обновлялся когда пользователь переходит на главную, но при этом так же нужно чтобы компонент обновлялся когда меняется его store, а если выдавать false этого не произойдёт. Поэтому я и делал 2 раза true.

как мне кажется лучше использовать componentWillReceiveProps, в моём случае.

а то что рендер вызывается несколько раз, связано с тем что я отправляю лишние action в Redux.