Async Storage в PURE React Native

Давайте узнаем, как интегрировать Async Storage в PURE React Native.

Шаг 1: Установите асинхронное хранилище

Сначала установим async Storage с помощью следующей команды

npm i @react-native-async-storage/async-storage
Войдите в полноэкранный режим Выйти из полноэкранного режима

Async storage похоже на Local storage, но оно предназначено для приложений, в то время как Local storage предназначено для веб.

Шаг 2: CRUD с асинхронным хранилищем

Async Store (файл-помощник)
import AsyncStorage from "@react-native-async-storage/async-storage";

// Storing Data
const storeData = async (storageKey: string, value: any) => {
  try {
    const jsonValue = typeof value === 'string' ? value : JSON.stringify(value);
    await AsyncStorage.setItem(storageKey, jsonValue);

    return { msg: `Saving successful` };
  } catch (error) {
    // saving error
    console.log(error);
    return { error: true, msg: `Saving failed` };
  }
}

// Getting Data
const getStringValue = async (storageKey: string) => {
  try {
    const value = await AsyncStorage.getItem(storageKey)
    return value
  } catch (error) {
    // error reading value
    console.log(error);
  }
}
const getObjectValue = async (storageKey: string) => {
  try {
    const jsonValue = await AsyncStorage.getItem(storageKey)
    return jsonValue !== null ? JSON.parse(jsonValue) : null;
  } catch (error) {
    // error reading value
    console.log(error);
  }
}

// Updating Data
const updateObjectData = async (storageKey: string, value: any) => {
  try {
    const jsonValue = typeof value === 'string' ? value : JSON.stringify(value);
    await AsyncStorage.mergeItem!(storageKey, jsonValue);

    const newData = typeof value === 'string' ? await getStringValue(storageKey) : await getObjectValue(storageKey);

    return { msg: `Updating successful`, data: newData };
  } catch (error) {
    // updating error
    console.log(error);
    return { error: true, msg: `Updating failed` };
  }
}
const upsertObjectData = async (storageKey: string, value: any) => {
  try {
    const jsonValue = typeof value === 'string' ? value : JSON.stringify(value);
    const oldValue = await AsyncStorage.getItem(storageKey);

    if (oldValue === null) {
      await storeData(storageKey, value);
    } else {
      await AsyncStorage.mergeItem!(storageKey, jsonValue);
    }

    const newData = typeof value === 'string' ? await getStringValue(storageKey) : await getObjectValue(storageKey);

    return { msg: `Updating successful`, data: newData };
  } catch (error) {
    // upserting error
    console.log(error);
    return { error: true, msg: `Updating failed` };
  }
}

// Remove Data
const removeData = async (storageKey: string) => {
  try {

    await AsyncStorage.removeItem(storageKey);
    return { msg: `Removing successful` };

  } catch (error) {
    // removing error
    console.log(error);
    return { error: true, msg: `Removing failed` };
  }
}


// MUTLI FUNCS
const multiGetData = async (storageKeys: string[]) => {
  try {

    const valuesArray = await AsyncStorage.multiGet(storageKeys)
    return valuesArray;

  } catch (error) {
    // multi getting error
    console.log(error)
  }
}
const multiSetData = async (keyValueArray: [string,string][]) => {
  try {
    /*
      keyValueAray: [
       ["@MyApp_user", "value_1"],
       ["@MyApp_user", "value_1"]
     ]
    */
    const valuesArray = await AsyncStorage.multiSet(keyValueArray)
    return valuesArray;

  } catch (error) {
    console.log(error)
  }
}
const multiUpdateData = async (keyValueArray: [string,string][], value: any) => {
  try {
    /*
      keyValueAray: [
       ["@MyApp_user", "value_1"],
       ["@MyApp_user", "value_1"]
     ]
    */

    await AsyncStorage.multiMerge!(keyValueArray);
    const keys = keyValueArray.map(item => item[0]);
    const newMultiData = await multiGetData(keys);

    return { msg: `Updating successful`, data: newMultiData };
  } catch (error) {
    // multi updating error
    console.log(error);
    return { error: true, msg: `Updating failed` };
  }
}
const multiRemoveData = async (storageKeys: string[]) => {
  try {

    await AsyncStorage.multiRemove(storageKeys)
    return { msg: `Removing successful` };

  } catch (error) {
    // multi removing error
    console.log(error);
    return { error: true, msg: `Removing failed` };
  }
}

// SPECIALS
const getAllStorageKeys = async () => {
  try {

    const keys = await AsyncStorage.getAllKeys()
    return keys;

  } catch (error) {
    // read key error
    console.log(error)
  }
}
const clearStore = async () => {
  try {
    await AsyncStorage.clear();
    return { msg: `Store clearing successful` };
  } catch (error) {
    // clearing error
    console.log(error);
    return { error: true, msg: `Store clearing failed` };
  }
}

export const AsyncStoreKeyMap = {
  appSettings: 'appSettings',
  userProfile: 'userProfile',
  userProgress: 'userProgress',
}

const AsyncStore = {
  storeData,
  getStringValue, getObjectValue,
  updateObjectData, upsertObjectData,
  removeData,

  multiSetData,
  multiGetData,
  multiUpdateData,
  multiRemoveData,

  getAllStorageKeys,
  clearStore,
};

export default AsyncStore;
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 3: Как использовать?

import AsyncStore, { AsyncStoreKeyMap } from '../../../utils/AsyncStore';

AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { themeColor: color });
AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { isDarkTheme: !props.isDarkTheme });
AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { isSoundOn: !props.isSoundOn });
Войти в полноэкранный режим Выйти из полноэкранного режима

Как использовать Redux в React Native компоненте?

// ___________________ root
import React from 'react';
import { connect } from 'react-redux';
import { NavigationProp } from '@react-navigation/native';

// ___________________ helpers
import Toast from 'react-native-toast-message';
import { rootVariables } from '../../rootStyles/variables';

// ___________________ async store
import AsyncStore, { AsyncStoreKeyMap } from '../../../utils/AsyncStore';

// ___________________ redux store
import { IRootState } from '../../store/store';
import { IAppSettingState } from '../../store/reducers/appSettingsReducer';

import appSettingsActions from '../../store/actions/appSettingsAction';
import userProgressActions from '../../store/actions/userProgressAction';



interface propsInterface extends IAppSettingState {
  navigation: NavigationProp<any>,
  app: {
    updateThemeColor: typeof appSettingsActions.updateThemeColor,
    updateIsDarkTheme: typeof appSettingsActions.updateIsDarkTheme,
    updateIsVibrationOn: typeof appSettingsActions.updateIsVibrationOn,
    updateIsSoundOn: typeof appSettingsActions.updateIsSoundOn,
    resetDefault: typeof appSettingsActions.resetDefault,
  },
  progress: {
    updateRank: typeof userProgressActions.updateRank,
    updateLevel: typeof userProgressActions.updateLevel,
    updateXP: typeof userProgressActions.updateXP,
    resetDefault: typeof userProgressActions.resetDefault,
  },
}



function SettingScreen(props: propsInterface) {
  const updateThemeColor = async (color: string) => {
    props.app.updateThemeColor(color);
    AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { themeColor: color });
  }

  const updateIsDarkTheme = async () => {
    props.app.updateIsDarkTheme(!props.isDarkTheme);
    AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { isDarkTheme: !props.isDarkTheme });
  }

  const updateIsSoundOn = async () => {
    props.app.updateIsSoundOn(!props.isSoundOn);
    AsyncStore.upsertObjectData(AsyncStoreKeyMap.appSettings, { isSoundOn: !props.isSoundOn });
  }


  const handleResetDefault = () => {
    props.app.resetDefault();
    AsyncStore.removeData(AsyncStoreKeyMap.appSettings);

    Toast.show({
      type: 'success',
      text1: 'Restore Default Successful',
      text2: 'Restore all default settings',
      topOffset: rootVariables.toastTopOffset,

    })
  }

  const handleResetProgress = () => {
    props.progress.resetDefault();
    AsyncStore.removeData(AsyncStoreKeyMap.userProgress);

    Toast.show({
      type: 'success',
      text1: 'Reset Progress Successful',
      text2: 'Reset all of your progress',
      topOffset: rootVariables.toastTopOffset,
    })
  }

  return (
    <SettingScreen/>
  );
}


const mapStateToProps = (state: IRootState) => {
  return {
    ...state.app,
  }
}

const mapDispatchToProps = (dispatch: any) => {
  return {
    app: {
      updateThemeColor: (color: string) => dispatch(appSettingsActions.updateThemeColor(color)),
      updateIsDarkTheme: (isDarkTheme: boolean) => dispatch(appSettingsActions.updateIsDarkTheme(isDarkTheme)),
      updateIsVibrationOn: (isVibrationOn: boolean) => dispatch(appSettingsActions.updateIsVibrationOn(isVibrationOn)),
      updateIsSoundOn: (isSoundOn: boolean) => dispatch(appSettingsActions.updateIsSoundOn(isSoundOn)),
      resetDefault: () => dispatch(appSettingsActions.resetDefault()),
    },

    progress: {
      updateRank: (rank: string) => dispatch(userProgressActions.updateRank(rank)),
      updateLevel: (level: number) => dispatch(userProgressActions.updateLevel(level)),
      updateXP: (xp: number) => dispatch(userProgressActions.updateXP(xp)),
      resetDefault: () => dispatch(userProgressActions.resetDefault()),
    },
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(SettingScreen)
Войти в полноэкранный режим Выход из полноэкранного режима

Блог NEXT появится к 27 мая

Что будет дальше?

1. Скроллинг с помощью PURE React Native

2. Проект с Pure React Native

3. Подробнее о разработке приложений

4. Как развернуть приложение в playstore

5. Безумные вещи с JavaScript/TypeScript

6. Написание автоматических тестов для любого сервера

7. Как создать Android APP без XP с помощью Expo

(включая генерацию apk)

Есть сомнения?

Оставьте комментарий или свяжитесь со мной @SilveLEAF в Twitter или Linkedin.

Хотите узнать обо мне больше? Заходите сюда!
SilvenLEAF.github.io

Оцените статью
Procodings.ru
Добавить комментарий