React Router v4 Перенаправление не работает

У меня есть маршрут, который перенаправляет после проверки условия вроде этого

<Route exact path="/" render={()=>(
Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store}/>)}/>

URL-адрес изменяется, когда условие истинно, но компонент не установлен. Остальная часть кода компонента выглядит следующим образом.

render() {
    return (
      <div>
        ...
        <Route exact path="/" render={()=>(
          Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store} />         
        )} />
        <Route path="/intro" render={()=>(<IntroWizard state={Store.userInfo}/>)} />
        <Route path="/home" render={()=>(<Home state={Store}/>)} />
        <Route render={()=>(<h1>404 Not Found</h1>)} />
        <Footer />
      </div>
    );
  }

Мой компонент приложения содержится в BrowserRouter, таком как thi

ReactDOM.render(<BrowserRouter>
    <App/>
</BrowserRouter>,
  document.getElementById('root')
);

когда я нахожу URL-адрес непосредственно в браузере, так как компонент localhost: 3000/intro успешно установлен, но когда он проходит через перенаправление, он не отображает компонент. Как это исправить?

Изменить

Итак, одна деталь отсутствовала, и я попытался создать еще один проект, чтобы воспроизвести проблему. Мой компонент приложения является наблюдателем от mobx-реакции и экспортируется, как показано ниже.

let App = observer(class App { ... })
export default App

Я создал это репо с образцом кода, чтобы воспроизвести проблему, которую вы можете использовать. https://github.com/mdanishs/mobxtest/

Итак, когда Компоненты завернуты в наблюдателя mobx-реагирования, перенаправление не работает, он отлично работает

Ответ 1

Аскер опубликовал проблему на GitHub и получил это, по-видимому, неопубликованное скрытое руководство (правка: теперь опубликовано), которое мне тоже помогло. Я публикую это здесь, потому что столкнулся с той же проблемой и хочу, чтобы другие избегали нашей боли.

Проблема состоит в том, что mobx-реагировать и реагировать-редукс предоставляют свои собственные функции shouldComponentUpdate() которые только проверяют изменения проп, но маршрутизатор реакции отправляет состояние через контекст. Когда местоположение меняется, оно не меняет реквизиты, поэтому не запускает обновление.

Способ обойти это состоит в том, чтобы передать местоположение как опору. В приведенном выше руководстве перечислено несколько способов сделать это, но самый простой - просто обернуть контейнер компонентом более высокого порядка withRouter():

export default withRouter(observer(MyComponent))

или для редукса:

export default withRouter(connect(mapStateToProps)(MyComponent))

Ответ 2

Вы должны визуализировать только Redirect в вашем методе рендеринга:

render() {
  return (<Redirect to="/" />);
}

но вот мое любимое решение без использования компонента Redirect

  1. импорт import { withRouter } from 'react-router-dom';
  2. export default withRouter(MyComponent);
  3. Наконец, в вашем методе действий предположим, что handlingButtonClick
handlingButtonClick = () => {
  this.props.history.push("/") //doing redirect here.
}

Ответ 3

Будьте осторожны при составлении Router с другими компонентами, такими как поставщики перевода, поставщики тем и т.д. Через некоторое время я обнаружил, что ваше приложение должно быть строго обернуто маршрутизатором, например:

<Provider store={store}>
  <ThemeProvider theme={theme}>
    <TranslationProvider
      namespaces={['Common', 'Rental']}
      translations={translations}
      defaultNS={'Common'}
    >
      <Router>
        <App />
      </Router>
    </TranslationProvider>
  </ThemeProvider>
</Provider>

Надеюсь, что это поможет кому-то.

Ответ 4

Вам не хватает/перед входом

<Route exact path="/" render={()=>(
  Store.isFirstTime ? <Redirect to="/intro" /> : <Home state={Store} />         
)} />