首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将链式动作放入何处?

将链式动作放入何处?
EN

Stack Overflow用户
提问于 2017-08-16 00:40:17
回答 1查看 697关注 0票数 1

非常简单的用例:我有操作/事件,这些操作/事件将导致执行ajax请求,然后更新列表。

问题是,我不确定如何(具体来说,当页面被更改时从哪里开始请求一个新列表)。

redux商店

代码语言:javascript
复制
const defaultStore = {
  list: [],
  page: 1    
};

包装组件

代码语言:javascript
复制
const wrapper = props => (
  <div>
    <List {...props}> {/* This list should have page controls */}
      <PageControls {...props} />
    </List>
    <List /> {/* This list should not have page controls */}
  </div>
);

列表组件

代码语言:javascript
复制
const List = props => (
  <div>
    {props.children} {/* render page controls if present */}
    {props.items.map((item, k) => <div key={k}>item</div>
  </div>
);

寻呼机控制组件

代码语言:javascript
复制
const PageControls = props => (
  <div>
    <span onClick={props.changePage(-1)}>Backward</span>
    <span onClick={props.changePage(1)}>Forward</span>
  </div>
);

actionCreator

代码语言:javascript
复制
function changePage(delta) {
  return {
    type: 'CHANGE_PAGE',
    delta
  };
}

// utilizes react-thunk middleware
function getList(page = 1) {
  return dispatch => 
    axios.get(`/path/to/api?page=${page}`)
      .then(res => dispatch(updateList(res.data));
}

function updateList(newList) {
  return { 
    type: 'UPDATE_LIST',
    newList
  };
}

减速机

代码语言:javascript
复制
function reducer(state = {}, action) {
  switch(action.type) {
    case 'CHANGE_PAGE':
      return {...state, page: state.page + action.delta};
    case 'UPDATE_LIST':
      return {...state, list: action.newList};
    default:
      return state;
  }
}

在这一点上,我可以做几件事--我可以让每个应该触发列表更新分派操作的actionCreator:

代码语言:javascript
复制
function changePage(delta) {
  return dispatch => {
    dispatch({
      type: 'CHANGE_PAGE',
      delta
    });

    return dispatch(getList(store.getState() + delta));
  }
}

但这看起来很混乱。现在,我不仅必须得到我的store,而且我还必须把影响列表的每一个actionCreator都变成一堆东西。

我唯一能想到的另一件事是让我的<List>组件在某个地方使用store.subscribe来监视页面的更改,然后启动另一个getList操作,但这似乎也使我对什么会触发和不会触发状态更改的理解从Redux中移到了React组件中。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-16 01:22:56

也许你应该改变你的方法。我看不出有什么理由做两个更改页面和检索列表的操作。您只需按一下按钮发出getPage()动作,就可以传递下一个页码。这将检索项目列表并刷新页面。

在您的商店中,您应该跟踪当前页面,因此每次页面刷新时,getPage()参数的值也会更新。

例如(假设没有从API检索当前页面):

代码语言:javascript
复制
function getPage(page = 1) {
  return dispatch => 
    axios.get(`/path/to/api?page=${page}`)
      .then(res => dispatch(updatePage(res.data, page));
}

function updatePage(newList, currentPage) {
  return { 
    type: 'UPDATE_PAGE',
    newList,
    currentPage,
  };
}

并将所需组件连接到存储区,在您的示例中,将是ListPageControls组件。

代码语言:javascript
复制
const PageControls = props => (
  <div>
    <span onClick={props.getPage(props.currentPage - 1)}>Backward</span>
    <span onClick={props.getPage(props.currentPage + 1)}>Forward</span>
  </div>
);

这将使您能够维护简单和干净的代码。此外,还可以从多个而不是相关的组件触发它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45703458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档