【问题标题】:Screen does not updat while using react hook, unless I reload the app使用反应钩子时屏幕不会更新,除非我重新加载应用程序
【发布时间】:2020-09-17 11:38:34
【问题描述】:

我正在尝试使用电子邮件和密码登录我的用户。如果用户正确输入了他的凭据,我会使用 AsyncStorage 将身份验证状态更新为“true”。

在我的主 App.js 文件中,我检查了 AsyncStorage,以查看身份验证状态是“真”还是假。问题是当用户登录并且 AsyncStorage 得到更新时,除非我刷新应用程序,否则屏幕不会更新(使用 fastreload)。

我本质上需要的是一种在 App.js 中重新渲染或重新运行代码的方法,而无需用户关闭应用程序然后重新打开它。

这就是我正在做的事情

export default function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  AsyncStorage.getItem("auth").then((val) =>
    val == "true" ? setIsAuthenticated(true) : setIsAuthenticated(false)
  );

  return isAuthenticated ? (
    <NavigationContainer>
      <Stack.Navigator headerMode="none" initialRouteName="Home">
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Orders" component={Orders} />
      </Stack.Navigator>
    </NavigationContainer>
  ) : (
    <NavigationContainer>
      <Stack.Navigator headerMode="none">
        <Stack.Screen name="Welcome" component={Welcome} />
        <Stack.Screen name="Login" component={Login} />
        <Stack.Screen name="Signup" component={Signup} />
      </Stack.Navigator>
    </NavigationContainer>
  );

}

我应该怎么做,以便我的应用在“auth”更改为“true”时立即重定向用户

【问题讨论】:

  • 他们如何在子组件中进行身份验证?您可能需要为他们传递一个回调方法来通知应用程序身份验证已更改。 AsyncStorage 没有监听器功能 iirc
  • 我建议你使用像reducxcontext API这样的全局状态或状态容器,否则你会去进行大规模的螺旋钻
  • 不一定——简单地钻一个组件比为这样简单的事情设置全局状态解决方案要好得多——不是每个项目都需要 redux!

标签: reactjs react-native react-navigation


【解决方案1】:

尝试在 useEffect 挂钩中使用 AsyncStorage

useEffect(() => {
  AsyncStorage.getItem("auth").then((val) =>
  val == "true" ? setIsAuthenticated(true) : setIsAuthenticated(false)
);
}, []);

【讨论】:

  • 这不起作用,因为这只会在他们已经拥有的第一次渲染上运行。他们需要一种在“auth”项更改后更新它的方法,而这不会。
  • 我需要在异步存储中更改状态后重新渲染代码
【解决方案2】:

AsyncStorage API docs 没有显示出很好的更改侦听器功能,因此您可以尝试反复轮询存储以查看它是否已更改(不好),或者您可以创建一个通知回调函数它会在调用时更新状态,并在身份验证发生时将该函数作为要在您的子组件中调用的 prop 传递。

export default function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const checkAuthentication = () => {
    AsyncStorage.getItem("auth").then((val) =>
      val == "true" ? setIsAuthenticated(true) : setIsAuthenticated(false)
    );
  };

  useEffect(checkAuthentication, []);

  return isAuthenticated ? (
    <NavigationContainer>
      <Stack.Navigator headerMode="none" initialRouteName="Home">
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Orders" component={Orders} />
      </Stack.Navigator>
    </NavigationContainer>
  ) : (
    <NavigationContainer>
      <Stack.Navigator headerMode="none">
        <Stack.Screen name="Welcome" component={Welcome} />
        <Stack.Screen name="Login" component={Login} authChanged={checkAuthentication} />
        <Stack.Screen name="Signup" component={Signup} authChanged={checkAuthentication} />
      </Stack.Navigator>
    </NavigationContainer>
  );

useEffect 将在您的第一个页面加载时运行检查,然后在LoginSignup 组件中,使它们在登录状态发生更改时调用它们的authChanged 属性函数。这将导致状态更新。

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 2023-03-07
    • 2021-03-24
    • 2019-08-07
    • 1970-01-01
    • 2019-09-15
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多