为什么更新的状态没有反映在事件侦听器中:React Native、Hooks

IT技术 javascript reactjs react-native react-hooks
2021-05-13 22:19:28

我正在使用钩子来更新状态。在我的代码中,我有一个 AppState 事件侦听器,每当它触发时,我都会使用setAppState更新appState,但是事件侦听器中的 appState 没有更改。但该值正在侦听器之外更新。谁能解释为什么会这样?

这是我的代码:

    import React, { FunctionComponent, useEffect, useState } from "react"
    import { View, AppState, AppStateStatus } from "react-native"
    const Test: FunctionComponent<any> = (props: any) => {
        const [appState, setAppState] = useState < AppStateStatus > (AppState.currentState)
    
        useEffect(() => {
            AppState.addEventListener("change", _handleAppStateChange)
        },[])
    
        const _handleAppStateChange = (nextAppState: AppStateStatus) => {
         //appState not Changing here
            console.log(appState, "app state")
            if (appState.match(/inactive|background/) && nextAppState === "active") {
                console.log("App has come to the foreground!")
                activateRealtime()
            } else if (appState === "active" && nextAppState.match(/inactive|background/)) {
                console.log("App has come to background!")
            }
            setAppState(nextAppState)
        }
       //appState updated here
       console.log(appState, "app state")
        return <View />
    }
1个回答

在您的代码中 appState 是一个陈旧的闭包 linter应该告诉您您缺少依赖项。

我认为以下将起作用

const _handleAppStateChange = useCallback(
  (nextAppState) =>
    //use callback for state setter so you don't
    //  create needless dependency or (as you did)
    //  create a stale closure
    setAppState((currentAppState) => {
      //logs current appstate
      console.log(currentAppState, 'app state');
      if (
        currentAppState.match(/inactive|background/) &&
        nextAppState === 'active'
      ) {
        console.log('App has come to the foreground!');
        activateRealtime();
      } else if (
        currentAppState === 'active' &&
        nextAppState.match(/inactive|background/)
      ) {
        console.log('App has come to background!');
      }
      return nextAppState;
    }),
  //only pass function as _handleAppStateChange
  //  on mount by providing empty dependency
  []
);
useEffect(() => {
  AppState.addEventListener(
    'change',
    _handleAppStateChange
  );
  //clean up code when component unmounts
  return () =>
    AppState.removeEventListener(
      'change',
      _handleAppStateChange
    );
  //_handleAppStateChange is a dependency but useCallback
  //  has empty dependency so it is only created on mount
}, [_handleAppStateChange]);