簡體   English   中英

為什么 useCallback 返回一個空數組

[英]why does useCallback return an empty array

在本機應用程序中,

我正在嘗試從異步 function 獲取數據,這將使我返回 Promise<AlarmType[] | 未定義>

Q1。 因此,在 getAlarms.then() function 中,過濾了未定義的大小寫,並在我的控制台中打印了一個空數組。

在 vscode 中保存代碼后,控制台會打印一個包含正確數據的數組

Q2.我分別使用 useLayoutEffect 和 useEffect 的原因是我只是想將數據獲取代碼與反應導航 header setOption 代碼分開,但我不確定這是否是一個好習慣

有沒有更好的方法來做到這一點? 編輯:我正在使用 react-native-simple-alarm

  const [alarms, setAlarms] = useState<AlarmType[]>([]);

  const fetchData = useCallback(() => {
    getAlarms().then(response => {
      if (response) setAlarms(response);
      else console.log('undefined | empty array returned');
    });
  }, []);

  useLayoutEffect(() => {
    fetchData();
    const willFocusSubscription = navigation.addListener('focus', () => {
      fetchData();
    });
      console.log(alarms) // here, this function is called twice, and return empty array
    return willFocusSubscription;
  }, []);

  useEffect(() => {
    navigation.setOptions({
      headerLeft: () => <Icon name="trash-can-outline" size={30} 
          onPress={() => {
            deleteAllAlarms();
            fetchData();
          }}/>,
      headerTitle: 'Alarm',
      headerRight: () =><Icon name="plus" size={30} onPress={() => navigation.navigate('ModalStackView')}/>,
    });
  }, []);

在 getAlarms.ts 中

export const getAlarms = async () => {
  try {
    return await RNGetAlarms();
  } catch (error) {
    console.log('setting call error' + error);
  }
};

useLayoutEffect 在 React 的渲染周期之前被調用,這意味着在你的代碼中渲染 JSX 內容之前這個鈎子被調用

所以,如果在 JSX 渲染之前有任何要求,比如更改 header 名稱,顯示 header 左右按鈕等。

並且在初始渲染周期完成后調用 useEffect 當 JSX 代碼完成渲染 UI 部分時。

所以,我認為你的代碼應該如下所示:

const [alarms, setAlarms] = useState<AlarmType[]>([]);

const fetchData = useCallback(() => {
    getAlarms().then(response => {
        if (response) setAlarms(response);
        else console.log('undefined | empty array returned');
    });
}, []);

useEffect(() => {
    const willFocusSubscription = navigation.addListener('focus', () => {
        fetchData();
    });
    return willFocusSubscription;
}, [fetchData, navigation]);

useLayoutEffect(() => {
    navigation.setOptions({
        headerLeft: () => <Icon name="trash-can-outline" size={30} 
            onPress={() => {
                deleteAllAlarms();
                fetchData();
            }}/>,
        headerTitle: 'Alarm',
        headerRight: () =><Icon name="plus" size={30} onPress={() => navigation.navigate('ModalStackView')}/>,
    });
}, [deleteAllAlarms, fetchData, navigation]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM