如何解决无法访问带有 UseCallback 内部参数的函数
我有这个页面(屏幕),它通过参数接收一个 ID 号,在这个屏幕中,我尝试从我的动作(减速器)文件中调用一个动作函数并获得一个 API 调用,我以为我没有得到任何来自那个调用的数组中的信息,我相信问题出在调用中,但是我在操作函数的声明之后放置了一个控制台日志,但它没有打印,所以我认为它没有访问该函数,所以我认为问题在于通过 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); }); },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({ 图像: { 宽度: '100%',高度:300, },副标题:{ 字体大小:16, 文本对齐:'对齐', 边距垂直:20, fontWeight:'正常',},描述: { 字体大小:16, 文本对齐:'居中', 边距垂直:20, fontWeight: '粗体',
},dataContainer:{ width: '80%',alignItems: 'center',marginHorizontal: 40,actions: { marginVertical: 10,}); 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);
});
},loadEstad]);
console.log(estadId);
console.log(goles);
这样:
useEffect(()=>{
if (estadId) dispatch(userActions.fetchEstadistica(estadId));
},[estadId]);
假设您的减速器/操作代码是正确的,那么每次参数 estadId
更改时都应该调用 api。加载/刷新应该在减速器中设置,而不是在 screen
组件上。
需要牢记的几点:
-
不要等待派送。
-
console.log 在 promise 解析代码块之外的状态变量上不起作用。
-
下面这个不行。相反,您应该将加载变量设置为在 API 返回数据后更新的 redux 变量。
loadEstad(estadId).then(() => { setIsLoading(false); });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。