useAsyncStorage is NOT a HOOK
              
              #653
            
            Replies: 4 comments 14 replies
-
| Thanks @seancheung for feedback. The current implementation of  | 
Beta Was this translation helpful? Give feedback.
-
| 
 @gustavopch @pke I'm happy to open a new discussion about getting this right this time 🙏 | 
Beta Was this translation helpful? Give feedback.
-
| This isn't a hook since the beginning as it has nothing to do with state. Users think of it as a hook because its name is confusing(A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.). const wrapper = withAsyncStorage('mykey');
const MyComponent = () => {
  React.useEffect(() => {
    wrapper.getItem().then(res => {
      //...
    })
  }, []);
}The  The  function useAsyncStorage(key) {
  const [value, setValue] = React.useState();
  React.useEffect(() => {
    AsyncStorage.getItem(key).then((value) => setValue(value));
  }, [key]);
  React.useEffect(
    () =>
      // TODO: add a listener function to AsyncStorage which allows us to be notified when the value changes,
      // and it must return a function to remove the listener
      AsyncStorage.on("change", key, (value) => {
        setValue(value);
      }),
    [key]
  );
  const setItem = React.useCallback(
    async (value) => {
      await AsyncStorage.setItem(key, value);
      setValue(value);
    },
    [key]
  );
  const removeItem = React.useCallback(async () => {
    await AsyncStorage.removeItem(key);
    setValue(undefined);
  }, [key]);
  // TODO: mergeItem
  const handler = React.useMemo(
    () => ({ setItem, removeItem }),
    [setItem, removeItem]
  );
  return [value, handler];
}
function App() {
  const [item, { setItem, removeItem }] = useAsyncStorage("key");
} | 
Beta Was this translation helpful? Give feedback.
-
| Alternative: export function useAsyncStorage(key: string): AsyncStorageHook {
  return {
    getItem: useCallback((...args) => AsyncStorage.getItem(key, ...args), [key]),
    setItem: useCallback((...args) => AsyncStorage.setItem(key, ...args), [key]),
    mergeItem: useCallback((...args) => AsyncStorage.mergeItem(key, ...args), [key]),
    removeItem: useCallback((...args) => AsyncStorage.removeItem(key, ...args), [key])
  };
}Just wrap those functions with  | 
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Current behavior
According to hooks.js,
useAsyncStorageis a wrapper rather than a hook.It will either trigger unexpected re-rendring:
Or eslint hooks warnings:
A workaround is to disable warnings:
Expected behavior
useAsyncStorageis not a standard hook, it should be renamed to something likewithAsyncStoragerather than starting withusewhich will be treated as a hook.useAsyncStorageis designed to be a standard hook, the returned value should bememo-edRepro steps
Environment
Beta Was this translation helpful? Give feedback.
All reactions