【问题标题】:why updated state not reflected inside an event listener: React Native, Hooks为什么更新的状态没有反映在事件监听器中:React Native,Hooks
【发布时间】:2020-10-27 13:32:45
【问题描述】:

我正在使用挂钩来更新状态。在我的代码中,我有一个 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 />
    }

【问题讨论】:

  • 你应该修复这个const [appState, setAppState] = useState &lt; AppStateStatus &gt; AppState.currentState
  • 你怎么知道回调内部的状态没有更新? setAppState(nextAppState) 是函数中的最后一次调用。
  • 这不是问题。改变了它。我只是忘了在那里加上括号。
  • @DrewReese。它更新。但在侦听器内部,值仍然相同。
  • @JaredSmith State updates are asynchronous. 尽管这是真的,但说这会导致人们尝试await setState。此外,在功能组件中使用 useState 创建的设置状态的主要问题是stale closures

标签: javascript reactjs react-native react-hooks


【解决方案1】:

在您的代码中 appState 是 stale closure the 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]);

【讨论】:

    猜你喜欢
    • 2020-05-01
    • 2019-09-17
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 2019-11-06
    • 2017-06-17
    • 1970-01-01
    相关资源
    最近更新 更多