简体   繁体   English

React Hooks 和异步操作

[英]React Hooks and async operations

I'm new to React and JS.我是 React 和 JS 的新手。 I need help with 2 hooks I created: useSaveStorage and useGetStorage .我需要我创建的 2 个钩子的帮助: useSaveStorageuseGetStorage

My app receives data and must write it into my AsyncStorage, but I have null in my "@storage".我的应用程序接收数据并且必须将其写入我的 AsyncStorage,但我的“@storage”中有 null。 useRequest works correctly. useRequest工作正常。

I think it happened because it is asynchronous operations, but i don't know how to fix it.我认为它发生是因为它是异步操作,但我不知道如何解决它。 This is my hook useSaveStorage :这是我的钩子useSaveStorage

import React, {useState, useEffect} from 'react';
import AsyncStorage from '@react-native-community/async-storage';

export const useSaveStorage = (data, storage) => {
  const [error, setError] = useState(null);
  useEffect(() => {
    if (data) {
      AsyncStorage.setItem(storage, JSON.stringify(data))
        .then(res => {})
        .catch(err => {
          console.log(storage, setError(err));
        });
    }
  }, []);

  return {error};
};

Now useGetStorage :现在使用useGetStorage

import {useState, useEffect} from 'react';
import AsyncStorage from '@react-native-community/async-storage';

export const useGetStorage = storage => {
  const [store, setStore] = useState(null);
  useEffect(() => {
    console.log('useGetStorage: run');
    AsyncStorage.getItem(storage).then(res => {
      setStore(JSON.parse(res));
      console.log('store', store);
    });
  }, []);
  return {store};
};

And here is where I use it:这是我使用它的地方:

import React from 'react';
import {Text} from 'react-native';
import Loading from './screens/Loading';
import {useRequest} from '@umijs/hooks';
import {useSaveStorage} from './components/useSaveStorage';
import {useGetStorage} from './components/useGetStorage';

const Context = React.createContext(null);

export const AppContextProvider = ({children}) => {
  const {data, error, loading} = useRequest('http://10.0.2.2:3000/data', {
    initialData: {},
    loadingDelay: 5,
  });

  useSaveStorage(data, '@storage');
  const {store} = useGetStorage('@storage');

  const anyData = data || store;

  if (loading) {
    return <Loading />;
  }

  if (error) {
    <Text>Not a network</Text>;
  }

  return <Context.Provider value={anyData}>{children}</Context.Provider>;
};

export const useContextData = () => {
  return React.useContext(Context);
};

Since useSaveStorage is a React Hook, you can't put it inside an if condition.因为useSaveStorage是一个 React Hook,所以你不能把它放在if条件中。

I would suggest combining useSaveStorage with useGetStorage and expose store value and setStore function.我建议将useSaveStorageuseGetStorage结合useSaveStorage ,并公开store值和setStore函数。

useStorage.js使用Storage.js

/* imports */
export const useStorage = (storage) => {
  const [error, setError] = useState(null)
  const [loading, setLoading] = useState(false)
  const [data, setData] = useState(null)

  /*
  this will load data from storage once, when component is mounting,
  after that we will use internal state
  */
  useEffect(() => {
    setLoading(true)
    /* async logic to get data from store */
    asyncGetStorage(storage).then(value => {
      setData(value)
      setLoading(false)
    }).catch(setError)
  }, [])

  const setStore = (value) => {
    setLoading(true)
    /* Logic to set data,  */
    asyncSetStorage(storage, value).then(() => {
      setData(value)
      setLoading(false)
    }).catch(setError)

  }

  return { error, loading, store: data, setStore }
}

When you use it当你使用它


  const {data, error, loading} = useRequest('http://10.0.2.2:3000/data', {
    initialData: {},
    loadingDelay: 5,
  });
  const {error: storeError, loading: storeLoading, store, setStore } = useStorage('@storage')

  useEffect(() => {
    if (!error && !loading) {
      setStore(data)
    }

  }, [data, error, loading])

  const anyData = data || store

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM