更新上下文时不重新呈现组件 [英] Component not re-rendering when context is updated

查看:13
本文介绍了更新上下文时不重新呈现组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用上下文的组件,但在更新上下文时不重新呈现。

App.tsx

const AppContext = createContext({
  isLoggedIn: false,
  hasUserLoggedInBefore: false,
});
const useAppContext = () => useContext(AppContext);

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [hasUserLoggedInBefore, setHasUserLoggedInBefore] = useState(
    false
  );


  useEffect(() => {
    // to set up initial state
    asyncApiCall 
      .then((result) => {
        if (result["user"]) {
          setIsLoggedIn(true);
        } else {
          setIsLoggedIn(false);
        }

        if (result["hasUserLoggedInBefore"]) {
          setHasUserLoggedInBefore(true);
        } else {
          setHasUserLoggedInBefore(false);
        }
      });

    // to listen for changes
    // this does not seem to re-render <UserControl />
    listenToOnAuthChangeEvent((user) => {
      setIsLoggedIn(true);
      setHasUserLoggedInBefore(true);
    });
  });


  return (
    <AppContext.Provider
      value={{
        isLoggedIn,
        hasUserLoggedInBefore,
      }}
    >
      <div className="App">
        <Routes>
          <Route element={<UserControl />}>
            <Route path="/" element={<Functionality />} />
          </Route>
          <Route path="/signup" element={<Signup />} />
          <Route path="/login" element={<Login />} />
        </Routes>
      </div>
    </AppContext.Provider>
  );

}

和使用上下文的组件

UserControl.tsx

function UserControl() {
    const { isLoggedIn, hasUserLoggedInBefore } = useAppContext();

    if (!isLoggedIn) {
        return (
            <Navigate to={hasUserLoggedInBefore ? "/login" : "/signup"} />
        )
    }

    return (
        <Outlet />
    )
}

异步API调用将获取数据。如果用户没有登录,则根据他们过去是否登录过来显示注册或登录页面。如果他们已登录,则显示<Functionality />

据我所知,在API调用成功并调用set方法后,UserControl组件不会重新呈现为Display<Functionality /><Signup />组件将再次显示。

推荐答案

更新您上一个问题中的代码框以使用您的useEffectasyncApiCall调用我所看到的情况是,用户从主路径"/"开始,并且由于他们没有经过身份验证,他们被重定向到"/signup"页面。稍后,上下文状态更新,如果您想要查看Functionality组件,则必须导航回"/"。这可能是应用程序在第一个身份验证调用之前做出重定向决定的典型用例,解决方案是使用第三个不确定的状态来推迟重定向或呈现出口。

将初始isLoggedInhasUserLoggedInBefore状态更改为未定义。

const [isLoggedIn, setIsLoggedIn] = useState();
const [hasUserLoggedInBefore, setHasUserLoggedInBefore] = useState();

更新UserControl身份验证包装以检查此特定的未定义案例,并呈现加载指示符或空。

function UserControl() {
  const { isLoggedIn, hasUserLoggedInBefore } = useAppContext();

  // ... snip unrelated code

  if (isLoggedIn === undefined) return "... Checking Auth ...";

  if (!isLoggedIn) {
    return (
      <Navigate to={hasUserLoggedInBefore ? "/login" : "/signup"} replace />
    );
  }
  return <Outlet />;
}

这允许应用程序等待身份验证状态填充为状态,然后再呈现到登录或注册路由或受保护组件的Outlet的重定向。

这篇关于更新上下文时不重新呈现组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆