【问题标题】:Where should I be updating filtered data, in saga, reselect or reducers?我应该在哪里更新过滤数据,在 saga、reselect 或 reducer 中?
【发布时间】:2020-01-19 07:19:44
【问题描述】:

我目前正在使用reselectredux-sagas 和减速器。我有一个 filterParameter 状态,其中包含过滤参数值filterReducer.js

initialState = {
  filteredParameters: { ... } // null by default
}

过滤后的数据用在我的组件filters.js

// On change function
  const statusChange = event => {
    event.preventDefault();
    const { name, value } = event.target;

    setFilterParameters({ ...filterParameters, [name]: parseInt(value) });
  };

// Render
 {statuses && (
        <select name="statusId" onChange={statusChange}>
          <option>All</option>
          {statuses.map(status => (
            <option
              selected={
                filteredParameters && filteredParameters.statusId === status.id
              }
              key={status.id}
              name={status.name}
              value={status.id}
            >
              {status.icon} {status.name}
            </option>
          ))}
        </select>
      )}

// MapDispatchToProps
const mapDispatchToProps = dispatch => ({
  filterIdeas: parameters => dispatch(filterIdeas(parameters)),
  fetchCategories: () => dispatch(fetchCategoriesStart())
});

然后我有一个saga 设置来捕捉filter.sagas.js 中的这个动作:

function* filterCurrentIdeas({ payload: filteredParameters }) {
  try {
    yield put(setFilterParameters(filteredParameters));
    const ideas = yield select(selectBoardIdeasItems);

    // Custom function that does the filtering handling, this is shown below 

    const filterResults = yield call(
      filterIdeasByStatus,
      ideas,
      filteredParameters
    ); 
    yield put(filterIdeasSuccess(filterResults)); // This then gets fed into the reducer
  } catch (err) {
    console.log(err);
    return;
  }
}

这是我的减速机filter.reducer.js

    case BoardActionTypes.FILTER_IDEAS_SUCCESS:
      return {
        ...state,
        filteredItems: action.payload
      };

这是用于过滤filter.utils.js 的自定义实用程序助手:

export const filterIdeasByStatus = (ideas, filter) => {
  const { statusId, categoryId, orderBy, query } = filter;
  const orderedIdeas = orderBy ? _.orderBy(ideas, ["voteCount"]) : ideas;
  const regex = new RegExp(`${query}`, "gmius");

  const filtered = orderedIdeas.filter(
    idea =>
      (!statusId || (statusId && idea.IdeaStatus.id === statusId)) &&
      (!categoryId ||
        (categoryId && _.includes(idea.categoryIds, categoryId))) &&
      (!query || (query && idea.title.match(regex)))
  );

  return convertIdeasToObject(filtered);
};

目前这一切都有效,但我做错了还是有更好的方法或指南可以给我一个更好的例子?

提前致谢!

【问题讨论】:

    标签: reactjs redux react-redux redux-saga reselect


    【解决方案1】:

    帮助函数filterIdeasByStatus 是保持代码模块化和有条理的好方法。

    但是,鉴于setFilterParameters 是一个动作:

    setFilterParameters({ ...filterParameters, [name]: parseInt(value) });

    为什么要调用两次?

    1. filter.sagas.js in filterCurrentIdeas 传奇
    2. filters.js 组件

    通常你会想要在statusChange 上发送一个动作并让saga 过滤项目(就像你做的那样)。但是两次调用相同的操作可能会产生副作用。

    细致提示:注意 React 组件命名空间通常大写,即 filters.js 应该是 Filters.js。

    您也可以在Stack Exchange Code Review寻求最佳实践和/或寻求反馈

    希望您获得一些见解 :)

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多