从本地存储和URL哈希中复合状态



我已经写了以下还原器,它有效,但是感觉我正在进入突变土地,并且可能有更好的方法来实现这一目标。我有一个名为"阅读"的状态对象。可以从URL中的哈希(Hash(以及存储在读取对象中的旧阅读的记录中提取读数。第三种方法是从本地存储中的持久状态中提取它。我希望将URL提取的优先级提取以使共享变得容易。这种方法还可以吗,如果没有,您能指出我的方向正确吗?

import { GENERATE_READING, GET_READING_FROM_HASH } from '../constants/actionTypes';
import { REHYDRATE } from 'redux-persist/constants';
import getHashFromUrl from '../utils/getHashFromUrl';
import getReadingFromHash from '../utils/getReadingFromHash';
// Check if URL has hash and set initial state to that reading.
const initialUrlHash = getHashFromUrl(window.location.pathname);
const initialUrlReading = initialUrlHash ? getReadingFromHash(initialUrlHash) : null;
const initialState = {
  arr: initialUrlReading ? initialUrlReading.arr : [],
  hash: initialUrlHash ? initialUrlHash : '',
  time: 0,
  oldReadings: []
};
export const reading = (state = initialState, action) => {
  switch (action.type) {
    case GENERATE_READING: {
      let reading = action.reading;
      // If old readings exists, save new reading to array of old readings.
      if (state.oldReadings) {
        reading.oldReadings = [ {
          hash: reading.hash,
          time: reading.time,
          amount: reading.arr.length
        }, ...state.oldReadings ];
        reading.oldReadings = reading.oldReadings.slice(0, 5);
      }
      // Otherwise create new array and save reading to it.
      else {
        reading.oldReadings = [{
          hash: reading.hash,
          time: reading.time,
          amount: reading.arr.length
        }];
      }
      return { ...state, ...reading };
    }
    case GET_READING_FROM_HASH:
      // Used when restoring reading for old hash.
      return { ...state, ...action.reading };
    case REHYDRATE: {
      const incoming = action.payload.reading;
      // If hydrating from local storage, check for hash in url and append
      // that reading on top of reading from local storage.
      if (incoming) {
        const urlHash = getHashFromUrl(window.location.pathname);
        if (urlHash && incoming.hash !== urlHash) {
          const urlReading = getReadingFromHash(urlHash);
          return { ...state, ...incoming, ...urlReading };
        } else {
          return { ...state, ...incoming };
        }
      } else {
      return state;
      }
    }
    default:
      return state;
  }
};
export default reading;

我认为您可以使用Object.assign来避免突变并简化代码。例如,而不是let reading = action.reading,它仍然只是您可以执行const reading = Object.assign({}, action.reading)的原始对象的引用。从本质上讲,这是一个新的空对象,并将action.reading复制到其中。看一下文档,Object.assign对于这种类型的东西是无价的。

https://developer.mozilla.org/en-us/docs/web/javascript/Reference/global_objects/objects/object/assign/assign

最新更新