web-dev-qa-db-ja.com

onEnter Transitions with React Router and Redux Simple Router Dont Render New Route's Component

私はreact @ 0.14、redux @ 3.05、react-router @ 1.0.3、およびredux-simple-router @ 2.0.2を使用するアプリを持っています。ストアの状態に基づいて、一部のルートのonEnterトランジションを構成しようとしています。トランジションフックが正常に起動し、新しい状態をストアにプッシュします。これにより、URLが変更されます。ただし、ページに表示される実際のコンポーネントは、ルート一致の元のコンポーネントハンドラーであり、新しいURLの新しいコンポーネントハンドラーではありません。

これが私のroutes.jsファイルは次のようになります

export default function configRoutes(store) {
  const authTransition = function authTransition(location, replaceWith) {
    const state = store.getState()
    const user = state.user

    if (!user.isAuthenticated) {
      store.dispatch(routeActions.Push('/login'))
    }
  }

  return (
    <Route component={App}>
      <Route path="/" component={Home}/>
      <Route path="/login" component={Login}/>
      <Route path="/dashboard" component={Dashboard} onEnter={authTransition}/>
      <Route path="/workouts" component={Workout} onEnter={authTransition}>
        <IndexRoute component={WorkoutsView}/>
        <Route path="/workouts/create" component={WorkoutCreate}/>
      </Route>
    </Route>
  )
}

これが私のRoot.jsDOMに挿入されるコンポーネント

export default class Root extends React.Component {
  render() {
    const { store, history } = this.props
    const routes = configRoutes(store)

    return (
      <Provider store={store}>
        <div>
          {isDev ? <DevTools /> : null}
          <Router history={history} children={routes} />
        </div>
      </Provider>
    )
  }
}

明確にするために、「/ワークアウト」に移動すると、onEnter authTransitionフックが起動され、redux-simple-routerプッシュアクションがディスパッチされ、URLが「/ login」に変更されますが、ページにワークアウトコンポーネントが表示されます。 Redux DevToolsを見ると、state -> router -> location -> pathnameは '/ login'です。

状態の流れは

  1. @@初期化
  2. @@ ROUTER/UPDATE_LOCATION(/ workouts)
  3. @@ ROUTER/UPDATE_LOCATION(/ login)

店舗をルートに間違って渡していませんか?次のRouter/Update_Locationが機能しない理由がわかりません

7
Jon

遷移を制御するためにredux-simple-routerではなくreact-routerapi(replace)を使用したいことがわかりました。

const authTransition = function authTransition(nextState, replace, callback) {
  const state = store.getState()
  const user = state.user

  // todo: in react-router 2.0, you can pass a single object to replace :)
  if (!user.isAuthenticated) {
    replace({ nextPathname: nextState.location.pathname }, '/login', nextState.location.query)
  }

  callback()
}

また、注意してください。単一のオブジェクトを渡す場所でのreact-routerreplaceに関する多くのドキュメントを見ました。これはreact-router2.0-rc *用です。 react-router 1.0を使用している場合は、replace3の個別の引数を渡す必要があります。

12
Jon