2016-06-19 87 views
2

我一直在試圖弄清楚這一點,我越來越困惑。更新路線變化的Redux狀態

我想在每次離開或更改路線時重置/更改Redux狀態。我使用react-router-reduxhistory.listener調度動作,每次路由變化

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

行動的創建者:

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

減速

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 
    } 
} 

什麼混淆了我最,如果我刷新頁面或在頂部導航欄中點擊兩次路徑,則更新狀態,但即使動作和縮減器激活(在控制檯中顯示測試消息),單個路由更改也不會影響縮減狀態。

我在做什麼錯,在這裏發生了什麼?

回答

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> 

第1頁容器:

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()做到這一點。我在Reducer中有一個動作設置,我想要重置以重置其狀態,並從componentWillUnmount()方法派發動作。

您可能會遇到的一個問題是,使用React Router時,路由更改不會觸發刷新,並且組件不會在同一路由上重新掛載,例如,如果您有posts/new和posts /編輯/:id路由都使用相同的組件來編輯帖子,在這些路徑之間進行不會導致組件重新掛載。

因爲這個componentWillUnmount的()運行,同樣的組件將剛剛收到的新道具。因此,您可以使用componentWillReceiveProps(newProps)來執行比較並相應地進行更新。

如果您確實想要強制組件重新裝入,則需要確保要重新裝入的組件具有不同的鍵屬性,請參閱herehere以獲取更多信息。