Синхронизировать хранилище избыточности с местоположением маршрута реагирующего маршрутизатора (обновлять заголовок при изменении маршрута)

Я использую react-router-redux и пытаюсь обновить заголовок своего приложения, которое получает свое состояние из хранилища при каждом изменении маршрута (@@router/UPDATE_LOCATION)

В настоящее время я отправляю действия в componentWillMount, например:

  componentWillMount() {
    this.props.appActions.setHeader('New Block')
  }

Когда я вручную устанавливаю заголовок в componentWillMount на маршруте /blocks/new, и он является дочерним элементом "блоков" маршрута, которые имеют разные заголовки, это не работает, когда я возвращаюсь в history, потому что компонент маршрута blocks работает не смонтировать снова, он все еще смонтирован. Таким образом, заголовок по-прежнему New Block. А не то, каким был его собственный заголовок раньше, когда blocks монтировался, а new еще был размонтирован как дочерний.

(И когда я пытаюсь повернуть время вспять с помощью redux-devtools, что, кажется, происходит тогда, каждый раз, когда я возвращаюсь к точке, где компонент снова монтируется, он снова отправляет действие, и инструмент разработки получить еще одну посылку.)

Маршруты:

<Route path="begin" component={PlayerBeginContainer}>
    <IndexRoute component={PlayerOverview}/>
       <Route path="blocks" component={PlayerBlocks}>
         <Route path="new" component={PlayerNewBlock}/>
       </Route>
</Route>
...

Я пытался синхронизировать магазин при изменении маршрута, но:

if (action && action.type === UPDATE_LOCATION) {
 let path = action.payload.pathname.split('/')
 // Laboriously iterate through array to figure out what the new header state should be.
  // i.e. if (1 in split && split[1] === 'routeName')
  // or let lastPath = path[path.length - 1]
  // and getting parentPath would require more checking of whether it is the parent itself or not etc.
  // appHeader = 'routeHeader'
  return Object.assign({}, state, { appHeader: appHeader});
}

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

В заголовке я не могу использовать ничего, кроме this.props.location.pathname, чтобы попытаться выяснить, на каком маршруте я нахожусь, и сами компоненты не должны заморачиваться установкой заголовка (т.е. в componentWillMount).

Последним вариантом будет использование маршрутизатора onEnter, но я бы хотел, чтобы маршрутизатор был чистым, но, возможно, мне придется пойти на компромисс в этом вопросе.

Есть ли что-то, что мне здесь не хватает? Или какая-то библиотека, которая может мне в этом помочь?

TL;DR: Как я могу сообщить моему компоненту header, на каком маршруте мы находимся, без необходимости разбивать location.pathname, чтобы выяснить, где мы находимся?


person BlockChange    schedule 11.10.2016    source источник
comment
Вы можете просто получить все состояние местоположения в качестве опоры для вашего соответствующего компонента реакции в mapStateToProp, выбрав часть местоположения вашего состояния, которую вы дали react-router-redux. Если у вас есть это в качестве опоры, вы должны быть в состоянии делать то, что хотите. Это может привести к тому, что имя пути будет снова разделено, но это кажется чище, чем прослушивание действия UPDATE_LOCATION.   -  person iamnat    schedule 11.10.2016
comment
Помогает ли это: github.com/reactjs/ ?   -  person iamnat    schedule 11.10.2016
comment
@iamnat, дело в том, что я не использую params.id или query.filter, поэтому мой заголовок по-прежнему должен .split('/') указывать путь для каждого случая.   -  person BlockChange    schedule 11.10.2016


Ответы (1)


Это код из одной из моих кодовых баз. В этом приложении я использую хэш-историю, но я думаю, вы могли бы сделать то же самое с другие объекты истории тоже.

import {hashHistory} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';

const history = syncHistoryWithStore(hashHistory, store);
history.listen(location => {
   // here you can do something after location is updated
});

<Router history={history}>
 ....
</Router>

а затем в ваших компонентах вы можете получить некоторую информацию из state.routing:

function mapStateToProps(state) {
  return {
    current: state.routing.locationBeforeTransitions.pathname,
  };
}

export default connect(mapStateToProps)(App);

Чтобы изменить маршрут от какого-либо компонента, сделайте следующее:

import {push} from 'react-router-redux';
this.props.dispatch(push('/route'));
person Lukas Liesis    schedule 11.10.2016