React Native app only works after saving file twice

36 Views Asked by At

Basically, a request is made to an API and then the expected result is only presented on the screen after saving the file in vscode twice. The API is returning the correct result the first time, the problem seems to be linked to useEffect and the updating of the components on the screen, because when I update the desirable result is presented. I'm saving API data in AsyncStorage and then recovering. I have no idea if I'm doing it right or if there's a better way, but the point is that the app doesn't update the components the first time.

user.js (context)

import React, { createContext, useEffect, useState, useContext } from "react"
import AsyncStorage from "@react-native-async-storage/async-storage"

import ApiRequest from '../services/Api';

const UserContext = createContext({})

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState({})
  const [services, setServices] = useState([])

  useEffect(() => {
    let isSubscribed = true;

    const getStorage = async (isSubscribed) => {
      const storagedToken = await AsyncStorage.getItem('token');
      const storagedId = await AsyncStorage.getItem('id');

      if(storagedToken && storagedId) {
        isSubscribed ? getUser(storagedToken, storagedId) : null;
      }
    }

    getStorage(isSubscribed);

    return () => (isSubscribed = false);
  }, [])

  async function getUser(storagedToken, storagedId) {
    try {
      const resp = await ApiRequest.getUser(storagedToken, storagedId)
      let user = JSON.stringify(resp.Cadastro)
      
      await AsyncStorage.setItem('user', user);
    } catch (error) {
      console.log('Não foi possível recuperar os dados do usuário, tente novamente.')
    }
  }

  return (
    <UserContext.Provider value={{ user, currentService, services, setServiceDate, setServiceType, setCurrentService }}>
      {children}
    </UserContext.Provider>
  )
}

export const useUser = () => {
  return useContext(UserContext)
}

Api.js

import axios from 'axios';
import UrlGenerator from './UrlGenerator';

const ApiRequest =  {
        async getUser(token, id){ 
            try {
                const uri = await UrlGenerator.user();
                
                const resp = await axios.post(uri, {
                    Token: token, 
                    cadastroKey: id
                });

                return resp.data; 
            } catch (error) {
                //setState(error.toString());
                console.log(error);
            }
        }
}

export default ApiRequest;

WelcomeChamado.js

import React, { useEffect, useState } from 'react'
import { View, Image, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
import { LinearGradient } from 'expo-linear-gradient';
import { initialWindowMetrics, SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import NavBar from '../../../components/NavBar';

import { TextMuseo300, TextMuseo500 } from '../../../components/fonts/TextFonts';

import { theme } from '../../../global/theme';
import { TextInputMuseo300 } from '../../../components/fonts/TextInputFonts';
import AsyncStorage from '@react-native-async-storage/async-storage';

const { principalOne, principalTwo, principalThree, destaque, branco } = theme.colors;

import { Entypo } from '@expo/vector-icons';

import loadStoragedUser from '../../../helpers/getUser';

export function WelcomeChamado({ navigation }) {
  const insets = useSafeAreaInsets();
  const [user, setUser] = useState({});
  const [foto, setFoto] = useState('');

  useEffect(() => {
    async function getUser() {
      setUser(await loadStoragedUser());
    }
    const getInfo = async () => {
      const storagedFoto = await AsyncStorage.getItem('@lica:foto');
      setFoto(storagedFoto);
    }
    
    getInfo();
    getUser();
  }, []);


  const nextScreen = () => {
    navigation.navigate("AguardarChamado");
  }

  return (
    <ScrollView 
      showsVerticalScrollIndicator={false}
      contentContainerStyle={{
        flexGrow: 1,
    }}>
      <SafeAreaProvider initialMetrics={initialWindowMetrics} 
        style={
          styles.container, 
          {
            paddingTop: insets.top,
            paddingLeft: insets.left,
            paddingBottom: insets.bottom,
            paddingRight: insets.right,
          }
      }>
        <LinearGradient 
          start={{ x: 0, y: 0.5 }}
          end={{ x: 1, y: 0.5 }}
          locations={[0, 0.2, 0.4, 0.6, 0.8, 1]}
          colors={['#8EF4F0', '#D6FDFA', '#F8FEFE', '#F8FEFE', '#D6FDFA', '#8EF4F0']} 
          style={{
            flex: 1
        }}>
          <NavBar navigation={navigation} />
          <View style={{
            alignItems: 'center',
            marginTop: '5%'
          }}>
            <TextMuseo300 style={{
              color: '#2E8F71',
              marginTop: '1%',
              fontWeight: 'bold',
              marginBottom: 10
            }}>Olá</TextMuseo300>
            <View style={{
              justifyContent: 'center',
              alignItems: 'center',
            }}>
              <Image 
                source={{ uri: `data:image/gif;base64,${foto}` }}
                style={{ 
                  width: 100, 
                  height: 100,
                  borderRadius: 50,
                  borderWidth: 1,
                  borderColor: destaque,
                }}
                resizeMode="cover"
              />
              <View style={{
                position: 'absolute',
                top: -5,
                right: 0,
                backgroundColor: '#2E8F71',
                width: 32,
                height: 32,
                borderRadius: 16,
                paddingLeft: 2,
                alignItems: 'center',
                justifyContent: 'center'
              }}>
                <Entypo 
                  name="bell"
                  size={25}
                  color="#FFF"
                />
              </View>
            </View>
            <TextMuseo300 style={{
              color: '#2E8F71',
              marginTop: '1%',
              fontWeight: 'bold',
              marginTop: 10
            }}>{user?.CadastroNome}</TextMuseo300>
            <TextMuseo300 style={{
              color: '#2E8F71',
              marginTop: '1%'
            }}>{user?.CadastroUser}</TextMuseo300>
          </View>

          <View style={{
            marginTop: 30,
            alignItems: 'center',
          }}>
            <TextMuseo300 style={{
              color: '#2E8F71',
              marginTop: '2%',
              maxWidth: 120,
              fontSize: 20,
              textAlign: 'center'
            }}>Você está disponível para receber chamados?</TextMuseo300>

            <TouchableOpacity onPress={nextScreen}>
              <View style={{
                justifyContent: 'center',
                alignItems: 'center',
                backgroundColor: '#2E8F71',
                borderRadius: 10,
                width: 120,
                height: 30,
                marginTop: 50
              }}>
                <TextMuseo300 style={{
                  color: '#FFF',
                  marginTop: '2%',
                  maxWidth: 120,
                  fontSize: 20,
                  fontWeight: 'bold',
                  textAlign: 'center'
                }}>Sim, estou.</TextMuseo300>
              </View>
            </TouchableOpacity>
          </View>
        </LinearGradient>
      </SafeAreaProvider>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  center: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});
0

There are 0 best solutions below