2016-06-19 17 views
2

私はしばらくこのことを理解しようとしてきましたが、ますます混乱しています。ルート変更時にRedux状態を更新します

退出するたびにルートを変更するたびにReduxの状態をリセット/変更したいと考えています。私はほとんどが混乱何

export function manualCategories(state=[], action) { 
    switch (action.type) { 
     case 'SELECT_MANUALS_CATEGORY': 
      [...] 

     case 'RESET_MANUALS_CATEGORY': 
      console.log('test reducer'); 
      return Object.assign({}, state, { 
       manualCategory: 'test' 
      }) 

     default: 
      return state 
    } 
} 

リデューサー

export function resetManualsCategory() { 
    return { 
     type: 'RESET_MANUALS_CATEGORY' 
    } 
} 

:私は毎回ルートが

history.listen(location => store.dispatch(resetManualsCategory())); 

アクションの作成者を変更するアクションを派遣history.listenerreact-router-reduxを使用しています、ページをリフレッシュするか最上部のナビゲーションで2回クリックすると状態が更新されますが、アクションとレデューサーが起動しても(コンソールにテストメッセージが表示されていても)1回のルート変更は影響を受けません。

私は間違って何をしていますか、実際何が起こっていますか?

答えて

9

react-router-reduxは、LOCATION_CHANGEアクションを提供します。アクションは、すべてのルート変更ですでにディスパッチされています。

import { LOCATION_CHANGE } from 'react-router-redux' 

export function manualCategories(state=[], action) { 
    switch (action.type) { 
     case LOCATION_CHANGE: 
      /* 
       action.payload is something like: 
       { 
       pathname: '/', 
       search: '', 
       hash: '', 
       state: null, 
       action: 'PUSH', 
       key: 'xwl8yl', 
       query: {}, 
       $searchBase: { 
        search: '', 
        searchBase: '' 
       } 
       } 
      */ 

     default: 
      return state 
    } 
} 
+0

は '' LOCATION_CHANGE''は '' @@ router/LOCATION_CHANGE''と同じですか? – spik3s

+0

はい。 @@ router/LOCATION_CHANGEも使用できますが、お勧めしません。 –

+0

私はこの問題を引き起こしていることを認識しましたが、この質問とは少し異なります。多分あなたは助けることができますか? http://stackoverflow.com/questions/37912180/react-router-redux-takes-two-clicks-on-a-link-to-update-location-state – spik3s

4

私は、ルートを変更するときの状態をリセットするために異なるアプローチを使用しました。履歴/ルータをリッスンする代わりに、ページのコンテナにcomponentWillMountイベントを使用して、「リセットページ」アクションを送信しました。 例:

ルータ:

<Provider store={store}> 
    <Router history={history}> 
    <Route path="/page1" component={Page1Container} /> 
    <Route path="/page2" component={Page2Container} /> 
    </Router> 
</Provider> 

のPage1コンテナ:

class Page1Container extends Component { 

    componentWillMount() { 
    this.props.resetPage() 
    } 

    render() { 
    // render Page1 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
    // ... 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    // ... 
    resetPage:() => { dispatch({type: 'PAGE1_RESET_PAGE'}) } 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Page1Container) 

リデューサー:

const initialState = null 

export function Page1Reducer (state = initialState, action) { 
    switch (action.type) { 
    case 'PAGE1_RESET_PAGE': { 
     state = initialState 
     break 
    } 

    // ... 
    } 
} 
+0

これは、何らかの理由で、使用されているコンポーネントの状態の一部をリセットする必要がある場合には、良い解決策であるようです。 – MattD

0

は現在、私はこれを行うにはcomponentWillUnmount()を利用しています。私はその状態をリセットするためにリセットしたいリデューサーにアクション設定を持っていて、componentWillUnmount()メソッドからアクションをディスパッチします。

この問題の1つは、React Routerを使用すると経路の変更がリフレッシュされず、コンポーネントが同じルートで再マウントされないためです。たとえば、投稿/新規と投稿/ edit /:id両方とも同じコンポーネントを使用して投稿を編集すると、これらのルート間を移動してもコンポーネントは再マウントされません。このためcomponentWillUnmount(の

ませ実行、同じ構成要素は、単に新しい小道具を受けるだろう。したがって、componentWillReceiveProps(newProps)を使用して、それに応じて比較および更新を実行することができます。

コンポーネントを強制的に再マウントする場合は、再マウントするコンポーネントのキー属性が異なることを確認する必要があります。詳細については、hereおよびhereを参照してください。

関連する問題