Unable to acess a Function with parameters inside of UseCallback

260 views Asked by At

I have this page (screen) that receives via Params an ID number, in this Screen, I try to call an Action Function from my Action (reducer) file and gets an API call, I thought I didn't get any information in the Array from that call, I believe that the issue was in the Call, but I put a Console log after the declaration on the Action Function, but it didn't print so I think it didn't access to that function, so I believe the issue is in the Call of that function via Dispatch.

I even tried to put a Breakpoint inside the UseEfect where I call the Function that calls the Dispatch Function but it never breaks I'm not sure where is the error, this is the Code:

  • Screen (where I suspect the issue is):

          ```import React, {useState, useCallback, useEffect} from 'react';
    
          import { ScrollView, Text, Image, StyleSheet, View } from 'react-native';
    
          import { useSelector, useDispatch } from 'react-redux';
    
          const ProductDetailScreen = props => {
              const playerId = props.route.params.id;
              const estadId = props.route.params.statId;
    
              const selectedPlayer = useSelector(state => state.jugadores.availablePlayers.find(prod => prod.id === playerId));
    
    
          const [isLoading, setIsLoading] = useState(false);
          const [isRefreshing, setIsRefreshing] = useState(false);
          const [error, setError] = useState();
    
          const goles = useSelector(state => state.jugadores.playerGoals);
    
          const dispatch = useDispatch();
    
          const loadEstad = useCallback (async (param) => {
              setError(null);
              setIsRefreshing(true);
              try {
                  await dispatch(userActions.fetchEstadistica(param));
              } catch (err){
                  setError(err.message);
              }
              setIsRefreshing(false);
          }, [dispatch, setIsLoading, setError]);
    
          useEffect(() => {       
              setIsLoading(true); 
              loadEstad(estadId).then(() => {
                  setIsLoading(false);
              });
          }, [dispatch, loadEstad]);
    
          console.log(estadId);
          console.log(goles);
    
          return (
              <ScrollView>
                  <Image style={styles.image} source={{ uri: selectedPlayer.imagen }} />
                  <View style={styles.dataContainer}>
                      <Text style={styles.description}>Numero: <Text style={styles.subtitle}>{selectedPlayer.numero}</Text></Text>
                      <Text style={styles.description}>Nombre Completo: <Text style={styles.subtitle}>{selectedPlayer.nombre_completo}</Text></Text>
                      <Text style={styles.description}>Posicion: <Text style={styles.subtitle}>{selectedPlayer.posicion}</Text> </Text>
                      <Text style={styles.description}>Edad: <Text style={styles.subtitle}>{selectedPlayer.edad}</Text></Text>
                      <Text style={styles.description}>Nacionalidad: <Text style={styles.subtitle}>{selectedPlayer.nacionalidad}</Text></Text>
                  </View>
              </ScrollView>
          );
      }
    

    ;

          export const screenOptions = navData => {
              return {
                  headerTitle: navData.route.params.nombre,
    
    
        }
          };
    
          const
    

    styles = StyleSheet.create({ image: { width: '100%', height: 300, }, subtitle: { fontSize: 16, textAlign: 'justify', marginVertical: 20, fontWeight:'normal', }, description: { fontSize: 16, textAlign: 'center', marginVertical: 20, fontWeight: 'bold',

              },
              dataContainer:{
                  width: '80%',
                  alignItems: 'center',
                  marginHorizontal: 40,
              },
              actions: {
                  marginVertical: 10,
                  alignItems: 'center',
              },
          });
    
          export default ProductDetailScreen
    
      ;```
    
  • This is my Action File:

    import ResultadoEstadistica from '../../models/estadistica/resultadoEstadistica';
    import PlayerEstadistica from '../../models/estadistica/playerEstatisticData';
    import Cards from '../../models/estadistica/cards';
    import Games from '../../models/estadistica/games';
    import Goals from '../../models/estadistica/goals';
    
    export const SET_JUGADORES = 'SET_JUGADORES';
    export const SET_ESTADISTICA = 'SET_ESTADISTICA';
    
    export const fetchJugadores = () => {
        return async (dispatch) => {
            //any async code here!!!
            try {
                const response = await fetch(
                    'https://alianzafc2021-default-rtdb.firebaseio.com/jugadores.json'
                );
    
                if (!response.ok) {
                    throw new Error('Algo salio Mal!');
                }
    
                const resData = await response.json();
                const loadedJugadores = [];
    
                for (const key in resData) {
                    loadedJugadores.push(
                        new Jugador(
                            key,
                            resData[key].altura,
                            resData[key].apellido,
                            resData[key].edad,
                            resData[key].fecha_nacimiento,
                            resData[key].iso_code,
                            resData[key].imagen,
                            resData[key].lugar_nacimiento,
                            resData[key].nacionalidad,
                            resData[key].nombre_completo,
                            resData[key].nombre_corto,
                            resData[key].nombres,
                            resData[key].numero,
                            resData[key].pais,
                            resData[key].peso,
                            resData[key].player_id,
                            resData[key].posicion
                        )
                    );
                }
    
                dispatch({ type: SET_JUGADORES, players: loadedJugadores });
            } catch (err) {
                throw err;
            }
        };
    }
    
    export const fetchEstadistica = player_id => {
        return async (dispatch) => {
            //any async code here!!!
            try {
                const response = await fetch(
                    `https://api-football-v1.p.rapidapi.com/v2/players/player/${player_id}.json`,
                    {
                        method: 'GET',
                        headers: {
                            'x-rapidapi-key': Here goes my API KEY,
                            'x-rapidapi-host': 'api-football-v1.p.rapidapi.com',
                            'useQueryString': 'true'
                        }
                    }
                );
    
                if (!response.ok) {
                    throw new Error('Algo salio Mal!');
                }
    
                const resData = await response.json();
                const loadesApiResult = [];
    
                console.log('***Impresion desde la accion***');
                console.log(resData);
                console.log('***Fin de Impresionc***');
    
                //Arrays de la Estadistica del Jugador
                const loadedEstadistica = [];
                const loadedCards = [];
                const loadedGoals = [];
                const loadedGames = [];
    
                for (const key in resData) {
                    loadesApiResult.push(
                        new ResultadoEstadistica(
                            resData[key].results,
                            resData[key].players
                        )
                    );
                }
    
                const apiData = loadesApiResult.players;
    
                for (const key in apiData) {
                    loadedEstadistica.push(
                        new PlayerEstadistica(
                            apiData[key].player_id,
                            apiData[key].player_name,
                            apiData[key].firstname,
                            apiData[key].lastname,
                            apiData[key].number,
                            apiData[key].position,
                            apiData[key].age,
                            apiData[key].birth_date,
                            apiData[key].birth_place,
                            apiData[key].birth_country,
                            apiData[key].nationality,
                            apiData[key].height,
                            apiData[key].weight,
                            apiData[key].injured,
                            apiData[key].rating,
                            apiData[key].team_id,
                            apiData[key].team_name,
                            apiData[key].league_id,
                            apiData[key].league,
                            apiData[key].season,
                            apiData[key].captain,
                            apiData[key].shots,
                            apiData[key].goals,
                            apiData[key].passes,
                            apiData[key].duels,
                            apiData[key].dribbles,
                            apiData[key].fouls,
                            apiData[key].cards,
                            apiData[key].penalty,
                            apiData[key].games,
                            apiData[key].substitutes,
                        )
                    );
                }
    
                const playerDataGames = loadedEstadistica.games;
    
                for (const key in playerDataGames) {
                    loadedGames.push(
                        new Games(
                            playerDataGames[key].apperences,
                            playerDataGames[key].minutes_played,
                            playerDataGames[key].lineups
                        )
                    );
                };
    
                const playerDataGoals = loadedEstadistica.goals;
    
                for (const key in playerDataGoals) {
                    loadedGoals.push(
                        new Goals(
                            playerDataGoals[key].total,
                            playerDataGoals[key].conceded,
                            playerDataGoals[key].assists,
                            playerDataGoals[key].saves
                        )
                    );
                };
    
                const playerDataCards = loadedEstadistica.cards;
    
                for (const key in playerDataCards) {
                    loadedCards.push(
                        new Cards(
                            playerDataCards[key].yellow,
                            playerDataCards[key].yellowred,
                            playerDataCards[key].red
                        )
                    );
                };
    
                dispatch({ type: SET_ESTADISTICA, estadistica: loadesApiResult, goles: loadedGoals, juegos: loadedGames, tarjetas: loadedCards });
            } catch (err) {
                throw err;
            }
        };
    };```
    
    

Finally this is my Redux Reducer just incase:

import { SET_JUGADORES, SET_ESTADISTICA } from "../actions/jugadores";

const initialState = {
    availablePlayers: [],
    estadistica: [],
    playerGoals: [],
    playerCards: [],
    playerGames: [],
}

export default (state = initialState, action) => {
    switch (action.type) {
        case SET_JUGADORES:
            return {
                ...state,
                availablePlayers: action.players,
            };
        case SET_ESTADISTICA:
            return{
                ...state,
                estadistica: estadistica,
                playerGoals: action.goles,
                playerCards: action.tarjetas,
                playerGames: action.juegos
            };
    }
    return state;
};

Sorry for the Format but is giving me some issues; Any Ideas what my Be the Problem?

Thank you.

1

There are 1 answers

6
Wen W On BEST ANSWER

there are a few issues with your screen code, so i recommend simplifying the logic to make sure it works before adding anything thing else.

replace this:

const loadEstad = useCallback (async (param) => {
          setError(null);
          setIsRefreshing(true);
          try {
              await dispatch(userActions.fetchEstadistica(param));
          } catch (err){
              setError(err.message);
          }
          setIsRefreshing(false);
      }, [dispatch, setIsLoading, setError]);

      useEffect(() => {       
          setIsLoading(true); 
          loadEstad(estadId).then(() => {
              setIsLoading(false);
          });
      }, [dispatch, loadEstad]);

      console.log(estadId);
      console.log(goles);

with this:

useEffect(()=>{
if (estadId) dispatch(userActions.fetchEstadistica(estadId));
},[estadId]);

Assuming your reducer/action code is correct, then this should call the api everytime the params estadId changes. The loading/refresh should be set in the reducer instead on the screen component.

a few things to keep in mind:

  1. Don't await for dispatch.

  2. console.log on state variables outside of promise resolving code block won't work.

  3. This below won't work. instead, you should set the loading variable as a redux variable that gets updated after the API comes back with data.

    loadEstad(estadId).then(() => { setIsLoading(false); });