我有这个页面(屏幕(,它通过Params接收一个ID号,在这个屏幕中,我试图从我的Action(reducer(文件中调用一个Action Function,并得到一个API调用,我认为我没有从那个调用中获得数组中的任何信息,我认为问题在call中,但我在Action Function上的声明之后放了一个Console日志,但它没有打印,所以我认为它没有访问该函数,所以我相信问题在于通过Dispatch调用该函数。
我甚至试图在UseEfect中放置一个断点,我在这里调用调用Dispatch函数的函数,但它从未中断。我不确定错误在哪里,这是代码:
-
屏幕(我怀疑问题所在(:
```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=样式表.create({图像:{宽度:"100%",高度:300,},副标题:{font大小:16,text对齐:"对齐",marginVertical:20,fontWeight:'正常',},说明:{font大小:16,text对齐:"居中",marginVertical:20,fontWeight:"bold",
}, dataContainer:{ width: '80%', alignItems: 'center', marginHorizontal: 40, }, actions: { marginVertical: 10, alignItems: 'center', }, }); export default ProductDetailScreen ;```
-
这是我的行动文件:
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; } }; };```
最后这是我的Redux Reducer,以防万一:
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;
};
对格式感到抱歉,但给了我一些问题;你知道我的问题是什么吗?
谢谢。
您的screen
代码存在一些问题,因此我建议在添加任何其他内容之前简化逻辑以确保其有效。
替换此:
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);
这个:
useEffect(()=>{
if (estadId) dispatch(userActions.fetchEstadistica(estadId));
},[estadId]);
假设您的reducer/action代码是正确的,那么每当参数estadId
更改时,它都应该调用api。加载/刷新应该在reducer中设置,而不是在screen
组件上设置。
需要记住的几件事:
不要等待调度。
console.log在promise解析代码块之外的状态变量上不起作用。
下面的这个不起作用。相反,您应该将加载变量设置为redux变量,该变量在API返回数据后更新。
loadEstad(estadId(。然后(((=>{setIsLoading(false(;});