无法访问UseCallback内部具有参数的函数



我有这个页面(屏幕(,它通过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组件上设置。

需要记住的几件事:

  1. 不要等待调度。

  2. console.log在promise解析代码块之外的状态变量上不起作用。

  3. 下面的这个不起作用。相反,您应该将加载变量设置为redux变量,该变量在API返回数据后更新。

    loadEstad(estadId(。然后(((=>{setIsLoading(false(;});

最新更新