Как получить значение из функции getData асинхронного хранилища?

#react-native #asyncstorage

Вопрос:

Я хочу сохранить имя пользователя в локальном хранилище, используя @react-native-async-storage/async-storage React Native. Когда я проверил console.log, имя пользователя было успешно сохранено, но при извлечении данных обратно на другой экран с помощью функции getData в нем указано значение null. Помогите мне разобраться в этой проблеме.

это мое storage.js файл, в котором я сохранил все функции асинхронного хранения.

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


const storeData = async (key, value) => {
    try {
        await AsyncStorage.setItem(key, value)
    } catch (e) {
        console.log('Error on saving')
    }
}

const getData = async (key) => {

    try {
        const value = await AsyncStorage.getItem(key)
        if (value !== null) {
            console.log('Promise', value)
            return value
        }
    } catch (e) {
        // error reading value
    }
}

export { storeData, getData };


 

это мой файл экрана входа в систему

 import React, { Component, useState } from 'react';
import { View, Text, Button, ScrollView, TextInput, TouchableHighlight, StyleSheet } from 'react-native';
import * as yup from 'yup'
import { Formik } from 'formik'
import { storeData } from '../utils/storage';

const Login = (props) => {

    const handleLogin = (name) => {
        storeData('username',name)
        props.navigation.navigate('Home')
    }
    
    return (
        <Formik
            initialValues={{
                name: '',
                password: ''
            }}
            onSubmit={values => Alert.alert(JSON.stringify(values))}
            validationSchema={yup.object().shape({
                name: yup
                    .string()
                    .required('Please, provide your name!'),
                password: yup
                    .string()
                    .min(4)
                    .max(10, 'Password should not excced 10 chars.')
                    .required(),
            })}
        >
            {({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
                <ScrollView style={styles.scrollb}>

                    <View style={styles.container}>
                        <Text style={styles.title}>LOGIN PAGE</Text>
                        <Text style={styles.subtitle}>Welcome Back.</Text>
                    </View>

                    <View style={styles.container2}>
                        <TextInput
                            style={styles.tinput}
                            placeholder="Username"
                            value={values.name}
                            onChangeText={handleChange('name')}
                            onBlur={() => setFieldTouched('name')}
                        />
                        {touched.name amp;amp; errors.name amp;amp;
                            <Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.name}</Text>
                        }
                    </View>
                    <View style={styles.container2}>
                        <TextInput
                            style={styles.tinput}
                            placeholder="Password"
                            value={values.password}
                            onChangeText={handleChange('password')}
                            placeholder="Password"
                            onBlur={() => setFieldTouched('password')}
                            secureTextEntry={true}
                        />
                        {touched.password amp;amp; errors.password amp;amp;
                            <Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.password}</Text>
                        }
                    </View>

                    <View style={styles.container3}>
                        <TouchableHighlight
                            style={{
                                borderRadius: 10,
                            }}>
                            <Button
                                title="Login"
                                borderRadius={25}
                                containerViewStyle={{ borderRadius: 25 }}
                                buttonStyle={{ width: 145, height: 45, borderRadius: 25 }}
                                accessibilityLabel="Learn more about this button"
                                onPress={() => handleLogin(values.name)}
                                disabled={!isValid}

                            />
                        </TouchableHighlight>
                    </View>

                </ScrollView>
            )}
        </Formik>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 24,
        backgroundColor: "#61dafb",
    },
    container2: {
        flex: 1,
        paddingTop: 14,
        paddingHorizontal: 24,
        backgroundColor: "#61dafb",
    },
    container3: {
        flex: 1,
        paddingTop: 284,
        paddingHorizontal: 34,
        backgroundColor: "#61dafb",
        borderRadius: 40,
    },
    title: {
        marginTop: 16,
        borderRadius: 6,
        backgroundColor: "#61dafb",
        color: "white",
        textAlign: "center",
        fontSize: 50,
        fontWeight: "bold",
    },
    subtitle: {
        borderRadius: 6,
        paddingLeft: 33,
        backgroundColor: "#61dafb",
        color: "white",
        textAlign: "left",
        fontSize: 30,
        fontWeight: '400',
    },
    tinput: {
        height: 50,
        textAlign: "center",
        paddingVertical: 8,
        backgroundColor: "white",
        borderRadius: 27,
    },
    scrollb: {
        backgroundColor: "#61dafb",
    },
});

export default Login;

 

Это мой файл на главном экране. Где я хочу получить это имя пользователя со страницы входа в систему через асинхронное хранилище.

 
import React, { Component, useEffect, useState } from 'react';
import { View, Text, ScrollView, TouchableHighlight, Image, StyleSheet } from 'react-native';
import { getData } from '../utils/storage';

const Home = (props) => {

  const [username, setUsername] = useState('');

  useEffect(() => {
    getData('username')
    console.log('useEffect',getData('username'))
  }, [])

  const CategoriesAr = [
    {
      name: "Business",
      path: "Business",
      imgURL: "https://img.icons8.com/clouds/100/000000/analytics.png",
    },
    {
      name: "Technology",
      path: "Technology",
      imgURL: "https://img.icons8.com/clouds/100/000000/transaction-list.png",
    },
    {
      name: "Science",
      path: "Science",
      imgURL: "https://img.icons8.com/clouds/100/000000/innovation.png",
    },
    {
      name: "Health",
      path: "Health",
      imgURL: "https://img.icons8.com/clouds/100/000000/client-company.png",
    }
  ]

  const GridItem = (gridProps) => {
    const { data } = gridProps;
    return (
      <>
        <TouchableHighlight onPress={() => props.navigation.navigate(data.path)}>
          <View style={styles.card}>
            <View style={styles.header}>
              <Text style={{ fontWeight: "bold", fontSize: 18 }}>{data.name}</Text>
            </View>
            <View style={styles.imgbody}>
              <Image
                style={styles.tinyLogo}
                source={{
                  uri: data.imgURL,
                }}
              />
            </View>
          </View>
        </TouchableHighlight>
      </>

    )
  }

  return (
    <ScrollView style={styles.sclb}>
      <Text style={styles.title}>Hi {username}</Text>
      <View style={styles.containerX}>
        {CategoriesAr.map((item) => <GridItem data={item} />)}
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  title: {
    marginTop: 16,
    borderRadius: 6,
    backgroundColor: "#61dafb",
    color: "white",
    textAlign: "center",
    fontSize: 50,
    fontWeight: "bold",
  },
  containerX: {
    flex: 1,
    flexWrap: "wrap",
    marginTop: 8,
    maxHeight: 400,
    backgroundColor: "#61dafb",

  },
  card: {
    height: 150,
    width: 150,
    backgroundColor: "white",
    alignItems: "center",
    borderRadius: 15,
    elevation: 10,
    padding: 10,
    margin: 22,

  },
  imgbody: {
    paddingTop: 20,
  },
  tinyLogo: {
    height: 90,
    width: 90,
  },
  header: {
    flexDirection: "row",
  },
  sclb: {
    backgroundColor: "#61dafb",
  }
});

export default Home;

 

Ответ №1:

Вам нужно поставить ожидание перед получением таких данных.

 useEffect(() => {
    (async()=>{
         await getData('username')
         console.log('useEffect',await getData('username'))
    })();
}, [])
 

Ответ №2:

 useEffect(() => {
     CallMethod()
}, [])
    

const CallMethod = async() =>{
      await getData('username')
}