SoFunction
Updated on 2025-03-09

ahooks encapsulate cookie localStorage sessionStorage method

introduction

This article is the ninth article in the ahooks source code series. The main goals of this series are as follows:

  • Deepen your understanding of React hooks.
  • Learn how to abstract custom hooks. Build your own React hooks tool library.
  • To cultivate the habit of reading and learning source code, the tool library is a good choice for reading source code.

Let’s take a look at how ahooks encapsulate cookie/localStorage/sessionStorage.

cookie

ahooks encapsulates useCookieState, a Hook that can store state in a cookie.

The hook usedjs-cookieThis npm library. I think the reasons for choosing it are as follows:

  • The package is small in size. Less than 800 bytes after compression. There is no other dependence on it. This is very important for ahooks, which is originally a tool library.
  • Better compatibility. Supports all browsers. And support any characters.

Of course, it has other features, such as supporting ESM/AMD/CommonJS import, etc.

The encapsulated code is not complicated. Let’s first look at the default value settings, and its priority is as follows:

  • This value is already present in the local cookie, then it will be taken directly.
  • The value set is a string, and it will be returned directly.
  • The value set is a function, execute the function and return the function execution result.
  • Returns the defaultValue set in options.
const [state, setState] = useState<State>(() => {
  // If there is a value, return directly  const cookieValue = (cookieKey);

  if (isString(cookieValue)) return cookieValue;
  // Define the default value of the cookie, but it is not synchronized to the local cookie  // You can customize the default value  if (isFunction()) {
    return ();
  }

  return ;
});

Let’s look at the logic of setting cookies —updateStatemethod.

  • In useupdateStateWhen the method is used, the developer can pass in new options - newOptions. It will merge with the options set by useCookieState. Finally, except for the third parameter of the set method that defaultValue will be passed through to the js-cookie.
  • Get the value of the cookie and judge the passed value. If it is a function, the result returned after execution is taken, otherwise the value will be directly taken.
  • If the value is undefined, clear the cookie. Otherwise, call the set method of js-cookie.
  • Finally, the value of the cookie and the method to set it.
// Set the cookie valueconst updateState = useMemoizedFn(
  (
    newValue: State | ((prevState: State) => State),
    newOptions:  = {},
  ) => {
    const { defaultValue, ...restOptions } = { ...options, ...newOptions };
    setState((prevState) => {
      const value = isFunction(newValue) ? newValue(prevState) : newValue;
      // Clear cookies when the value is undefined      if (value === undefined) {
        (cookieKey);
      } else {
        (cookieKey, value, restOptions);
      }
      return value;
    });
  },
);

return [state, updateState] as const;

localStorage/sessionStorage

ahooks encapsulates useLocalStorageState and useSessionStorageState. Storing the state in the localStorage and sessionStorage Hook.

The usage method of both is the same, because the official uses the same method to encapsulate. Let's take useLocalStorageState as an example.

You can see that useLocalStorageState is actually the result returned by calling the createUseStorageState method. The participation of this method determines whether it is a browser environment to determine whether to use localStorage. The reason is that ahooks needs to support server rendering.

import { createUseStorageState } from '../createUseStorageState';
import isBrowser from '../utils/isBrowser';

const useLocalStorageState = createUseStorageState(() => (isBrowser ? localStorage : undefined));

export default useLocalStorageState;

Let's focus on the createUseStorageState method.

First, the passed parameters are called. If an error is reported, it will catch in time. This is because:

  • You can see that the storage returned here may actually be undefined, and there will be catch processing afterwards.
  • Also, from thisissueYou can see that when the cookie is disabled, localStorage cannot be accessed.*There is also this discussion. (Strange knowledge has been added again)
export function createUseStorageState(getStorage: () => Storage | undefined) {
  function useStorageState<T>(key: string, options?: Options<T>) {
    let storage: Storage | undefined;
    // /alibaba/hooks/issues/800
    try {
      storage = getStorage();
    } catch (err) {
      (err);
    }
    // The code will be explained later}
  • Supports custom serialization methods. If not, it is direct.
  • Supports custom deserialization methods. If not, it is direct.
  • getStoredValue Gets the default value of storage, and returns the default value if there is no local value.
  • When the incoming key is updated, reassign the value.
// Custom serialization methodconst serializer = (value: T) => {
  if (options?.serializer) {
    return options?.serializer(value);
  }
  return (value);
};

// Custom deserialization methodconst deserializer = (value: string) => {
  if (options?.deserializer) {
    return options?.deserializer(value);
  }
  return (value);
};

function getStoredValue() {
  try {
    const raw = storage?.getItem(key);
    if (raw) {
      return deserializer(raw);
    }
  } catch (e) {
    (e);
  }
  // default value  if (isFunction(options?.defaultValue)) {
    return options?.defaultValue();
  }
  return options?.defaultValue;
}

const [state, setState] = useState<T | undefined>(() => getStoredValue());

// Execute when key is updateduseUpdateEffect(() => {
  setState(getStoredValue());
}, [key]);

Finally, there is the function that updates storage:

  • If the value is undefined, removeItem and remove the storage.
  • If it is a function, the result after execution is taken.
  • Otherwise, take the value directly.
// Set Stateconst updateState = (value?: T | IFuncUpdater<T>) => {
  // If undefined, remove the option  if (isUndef(value)) {
    setState(undefined);
    storage?.removeItem(key);
    // If it is a function, it is used to pass into the state and return the result  } else if (isFunction(value)) {
    const currentState = value(state);
    try {
      setState(currentState);
      storage?.setItem(key, serializer(currentState));
    } catch (e) {
      (e);
    }
  } else {
    // Set value    try {
      setState(value);
      storage?.setItem(key, serializer(value));
    } catch (e) {
      (e);
    }
  }
};

Summary and Induction

We often need to do the encapsulation of cookie/localStorage. The encapsulation of ahooks is relatively simple overall. The above is the detailed content of the ahooks encapsulation cookie localStorage sessionStorage method. For more information about ahooks encapsulation cookie localStorage sessionStorage, please pay attention to my other related articles!