2016-06-19 94 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以获取更多信息。