rehooks/ideas

useEtters

ezekielchentnik opened this issue · 1 comments

allow get and set by path

const get = (object, keys, defaultVal = null) => {
  // check if object actually exists
  if (typeof object === "object" && object !== null) {
    keys = Array.isArray(keys)
      ? keys
      : keys.replace(/(\[(\d)\])/g, ".$2").split(".");
    const value = keys.reduce(
      (obj, key) => (obj && obj[key] !== "undefined" ? obj[key] : null),
      object
    );
    return value !== null && typeof value !== "undefined" ? value : defaultVal;
  }
  return defaultVal;
};

const set = (obj = {}, keys, value) => {
  keys = Array.isArray(keys)
    ? keys
    : keys.replace(/(\[(\d)\])/g, ".$2").split(".");
  const key = keys[0];
  if (keys.length > 1) {
    keys.shift();
    obj[key] = set(obj[key], keys, value);
  } else {
    obj[key] = value;
  }
  return obj;
};

const useEtters = initialState => {
  const [state, setState] = useState(initialState);
  return [
    (keys, defaultVal) => get(state, keys, defaultVal),
    (keys, value) => setState(s => set(s, keys, value))
  ];
};

FYI typically getters/setters are collectively referred to as "accessors"