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.
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:
with this:
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 thescreen
component.a few things to keep in mind:
Don't await for dispatch.
console.log on state variables outside of promise resolving code block won't work.
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); });