【问题标题】:Converting API data in React-Redux: Action or Reducer在 React-Redux 中转换 API 数据:Action 或 Reducer
【发布时间】:2017-03-17 19:51:15
【问题描述】:

我有一个天气应用程序,它的 api 数据有不同的格式,所以我创建了一个方法对象,我可以将该数据转换为英制格式,并将时间从 UTC 转换为 GMT。

现在我在 reducer 中的数据上调用了这些方法。

问题:“可以”还是应该在将有效负载传递给减速器之前在相应的操作中完成转换?只是好奇这样的最佳做法是什么。

仅供参考:我使用 axios 作为基于 Promise 的 HTTP 客户端,使用 redux-promise-middlewareredux-lodgerredux-promise 作为商店中的中间件。

动作创建者:

export const fetchCurrentWeather = (city) => {
const url = `${CURRENT_ROOT_URL}&q=${city},us`;
const promise = new Promise((resolve, reject) => {
   axios.get(url)
     .then(res => resolve(res.data))
     .catch(err => reject(err));

});
return {
  type: FETCH_CURRENT_WEATHER,
  payload: promise
  };
};

减速机:

export default(state = initialState, action) => {
const data = action.payload;
switch (action.type) {
    case `${FETCH_CURRENT_WEATHER}_PENDING`:
        return {};
    case `${FETCH_CURRENT_WEATHER}_FULFILLED`:
    const prefix = 'wi wi-owm-';
    const code = data.weather[0].id;
    const icon = prefix + code;
        return {
            ...state,
            weatherData: {
              humidity: data.main.humidity,
              icon,
              name: data.name,
              pressure: unitConverter.toInchesHG(data.main.pressure),
              sunrise: unitConverter.toGMT(data.sys.sunrise),
              sunset: unitConverter.toGMT(data.sys.sunset),
              temp: unitConverter.toFarenheit(data.main.temp),
              winddir: unitConverter.toCardinal(data.wind.deg),
              windspd: unitConverter.toMPH(data.wind.speed)
            },
            isFetched: true
        };
    case `${FETCH_CURRENT_WEATHER}_REJECTED`:
        return {
            ...state,
            isFetched: true,
            err: data
        };
    default:
        return state;
  }
};

【问题讨论】:

    标签: reactjs redux react-redux reducers


    【解决方案1】:

    您可以在三个位置有效地处理原始数据:

    • 组件的render()函数

      这通常不是一个好主意,因为这意味着每次渲染组件时都会处理数据。如果您使用像 reselect 这样的包,您可以通过缓存来缓解性能问题,但即便如此,实际代码例如排序过滤应保存在mapStateToProps()中。

    • 在减速器中

      可以为 reducer 中的处理数据提供更好的情况,但我认为出于清晰和关注点分离的原因,这仍然不是最好的地方。 reducer 的工作非常明确——承认动作并将先前的状态与动作结果合并,其他任何事情都只会模糊责任和可测试性的界限。

    • 动作重击

      在我看来,动作 thunk 是一次性数据转换的正确位置,例如导入原始数据的规范化/转换。它不仅通常是一个明确的操作子任务(例如,获取天气数据 -> 将摄氏度转换为华氏度),而且它还具有不存储无用数据的额外优势,即使是暂时的状态。

      引用丹·阿布拉莫夫的话:

      ...动作对象[是]所发生的事情的最小表示,并且 状态对象 [是] 所需内容的最小表示 立即渲染。

    最后说明 - 选择器

    虽然我上面说过组件不是执行原始数据转换的好地方,但实际上我认为将 raw-data 存储在 redux-state 中是有道理的并根据需要使用reselect 之类的包通过selectors 呈现标准化或计算值。

    实现此目的的一种方法是使用selector 函数对原始数据的定义部分执行数据规范化。使用reselect 包,此转换将被缓存,因此只执行一次。它的优点是仅在需要时延迟转换数据。

    【讨论】:

    • 谢谢!我正在考虑将转换移动到动作的想法,因为它看起来就像我仍在执行和action 对数据和reducer 并没有真正假设这样做。我将签出reselect 包。再次感谢!
    猜你喜欢
    • 2019-02-21
    • 2016-05-01
    • 2019-05-16
    • 1970-01-01
    • 2018-11-08
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多