notrab / react-use-cart

React hook library for managing cart state
http://npm.im/react-use-cart
Apache License 2.0
367 stars 48 forks source link

REACT NATIVE IMPLEMETATION #90

Closed njoromyke closed 3 years ago

njoromyke commented 3 years ago

Hello there, just asking whether I can implement this package in react native.Can it work in react native? thanks @notrab

notrab commented 3 years ago

@ngahika01 I haven't ever tried, have you? Feel free to share any bugs you get in this issue.

njoromyke commented 3 years ago

how can one change the storage from using localStorage and use AsnycStorage package?

njoromyke commented 3 years ago

Running into this error in reactnative

undefined is not an object (evaluating 'window.localStorage.setItem') at node_modules\react-use-cart\dist\react-use-cart.cjs.development.js:40:21 in s etValue at node_modules\react-use-cart\dist\react-use-cart.cjs.development.js:184:8 in C artProvider

notrab commented 3 years ago

You should be able to pass a custom storage to the CartProvider props.

https://github.com/notrab/react-use-cart#props

I haven't actually tried, and I don't think it's tested either 😬

So let me know how you get on it. PRs welcome for any changes necessary 😄

Omerfrq commented 2 years ago

You might need to update the useLocalStorage file manually to make this work.

import * as React from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const getInitialItems = async (key, initialValue) => {
  try {
    const initialState = await AsyncStorage.getItem(key);

    return initialState !== null ? initialState : initialValue;
  } catch (error) {
    return initialValue;
  }
};

export default function useLocalStorage(
  key: string,
  initialValue: string,
): [string, (value: Function | string) => void, boolean] {
  const [storedValue, setStoredValue] = React.useState<any>(initialValue);
  const [isLoading, setLoading] = React.useState(true);

  React.useEffect(() => {
    getInitialItems(key, initialValue).then(res => {
      if (res) {
        setStoredValue(res);
        setLoading(false);
      }
    });
  }, []);

  const setValue = (value: Function | string) => {
    try {
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;

      setStoredValue(valueToStore);

      AsyncStorage.setItem(key, valueToStore);
    } catch (error) {
      console.log(error);
    }
  };

  return [storedValue, setValue, isLoading];
}
Omerfrq commented 2 years ago

Also the index file needs to have the updated logic because the async storage in react native is async

Need to Add this Action

  case 'INITIAL_STATE':
      return action.payload;
  const [state, dispatch] = React.useReducer(reducer, null);
  const [intialDispatch, setInitialDispatch] = React.useState(false);
  React.useEffect(() => {
    if (!isLoading && savedCart) {
      dispatch({
        type: 'INITIAL_STATE',
        payload: JSON.parse(savedCart),
      });
      setInitialDispatch(true);
    }
  }, [isLoading, savedCart]);

  React.useEffect(() => {
    if (intialDispatch) {
      saveCart(JSON.stringify(state));
    }
  }, [state, saveCart]);