2015-08-28 3 views
28

Я работаю над реактивным приложением с использованием реактивного маршрутизатора. У меня есть страница проекта, который имеет URL следующим образом:Компонент не перезагружается при изменении параметров маршрута

myapplication.com/project/unique-project-id 

При загрузке компоненты проекта, я инициировать запрос данных для этого проекта от мероприятия componentDidMount. Сейчас я бегу на вопрос, где, если я переключиться непосредственно между двумя проектами, так только изменяется идентификатор, как это ...

myapplication.com/project/982378632 
myapplication.com/project/782387223 
myapplication.com/project/198731289 

componentDidMount не запускается снова, так что данные не обновляются. Есть ли еще одно событие жизненного цикла, которое я должен использовать для запуска моего запроса данных или другой стратегии для решения этой проблемы?

+1

Не могли бы вы высказать свой код компонента? – Pcriulan

ответ

33

Если ссылка направляется на тот же маршрут только с другим параметром, это не перемонтирование, а получение новых реквизитов. Итак, вы можете использовать функцию componentWillReceiveProps(newProps) и искать newProps.params.projectId.

Если вы пытаетесь загрузить данные, я бы рекомендовал получать данные до того, как маршрутизатор обработает совпадение, используя статические методы для компонента. Проверьте этот пример. React Router Mega Demo. Таким образом, компонент будет загружать данные и автоматически обновляться при изменении параметров маршрута, не полагаясь на componentWillReceiveProps.

+0

Спасибо. Я смог получить эту работу, используя componentWillReceiveProps. Я до сих пор не совсем понимаю поток данных React Router Mega Demo. Я вижу статические fetchData, определенные на некоторых компонентах. Как вызывается эта статика с клиентской стороны маршрутизатора? – Constellates

+0

Отличный вопрос. Проверьте файл client.js и файл server.js. Во время цикла запуска маршрутизатора они вызывают файл fetchData.js и передают ему состояние. Сначала это немного запутывает, но потом становится немного яснее. –

+0

Придя к этому несколько месяцев спустя, и, будучи очень неопытным, я испытываю трудности с обновлением примеров с изменениями в реакции-маршрутизатора с выпуском 1.0. Возможно ли, что Router.run был заменен рендером ( {маршруты }}, el) - можем ли мы сделать выборку до того, как маршрутизатор обработает совпадение? – theTechnaddict

21

Если вам необходимо перемонтировать компонент при изменении маршрута, вы можете передать уникальный ключ к ключевому атрибуту вашего компонента (ключ связан с вашим путем/маршрутом). Таким образом, каждый раз, когда маршрут изменяется, ключ также изменяет, какие триггеры реагируют на компонент для размонтирования/повторного подключения. У меня есть идея от this answer

+0

это абсолютно здорово, спасибо! – davnicwil

+0

Спасибо. Это должно быть принято ответ –

0

react-router не работает, потому что он должен перемонтировать компоненты при любом изменении местоположения.

мне удалось найти решение этой ошибки, хотя:

https://github.com/ReactTraining/react-router/issues/1982#issuecomment-275346314

Короче говоря (см ссылку выше для полной информации)

<Router createElement={ (component, props) => 
{ 
    const { location } = props 
    const key = `${location.pathname}${location.search}` 
    props = { ...props, key } 
    return React.createElement(component, props) 
} }/> 

Это сделает его перемонтирования на любой URL изменение

4

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

import theThingsYouNeed from './whereYouFindThem' 

export default class Project extends React.Component { 

    componentWillMount() { 

     this.state = { 
      id: this.props.router.params.id 
     } 

     // fire action to update redux project store 
     this.props.dispatch(fetchProject(this.props.router.params.id)) 
    } 

    componentDidUpdate(prevProps, prevState) { 
     /** 
     * this is the initial render 
     * without a previous prop change 
     */ 
     if(prevProps == undefined) { 
      return false 
     } 

     /** 
     * new Project in town ? 
     */ 
     if (this.state.id != this.props.router.params.id) { 
      this.props.dispatch(fetchProject(this.props.router.params.id)) 
      this.setState({id: this.props.router.params.id}) 
     } 

    } 

    render() { <Project .../> } 
} 
+0

Спасибо, это решение работает для меня. Но мои настройки eslint жалуются на это: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md Что вы думаете о это? – Konekoya

+0

Да, на самом деле это не самая лучшая практика, извините за это, после отправки «fetchProject» ваш редуктор все равно обновит ваши реквизиты, я просто использовал это, чтобы сделать свою мысль, не поставив редукцию на место. – chickenchilli

+0

Hi chickenchilli, Я на самом деле все еще застрял в этом ... у вас есть другие предложения или рекомендуемые учебные пособия? Или я пока буду придерживаться вашего решения. Спасибо за вашу помощь! – Konekoya