为什么 useCallback return 是一个空数组

why does useCallback return an empty array

在 React 原生应用中,

我正在尝试从异步函数获取数据,这将使我返回 Promise

Q1。因此,在 getAlarms.then() 函数中,过滤了未定义的大小写,并在我的控制台中打印了一个 空数组。

并且在 vscode 中保存代码后,控制台打印一个包含正确数据的数组

Q2.the 我之所以分别使用 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]);