reactjs ReactuseEffect渲染两次

eqoofvh9  于 2022-11-29  发布在  React
关注(0)|答案(3)|浏览(147)

我知道React在使用这样的钩子时会渲染两次:

const [userPermissions, setUserPermissions] = useState();

//Use GET from myService to save to state
useEffect(() => {
  myService.canUserAccess(userId)
  .then(({userPermissions}) => setUserPermissions(userPermissions));
});

对于我的应用程序的逻辑来说,这是一个巨大的问题,因为我需要检查用户权限,如果权限不正确,则需要重定向用户:

useEffect(() => {
  console.log(userPermissions); //This is the output
  if(!userPermissions){ redirect(...)}
},[userPermissions, redirect]);

我一直在调试这一点,似乎有一个第一个'渲染':输出如下内容:

undefined

紧接着:

{ userPermissions: {...} }

按照我的应用程序逻辑,当userPermissions的状态第一次设置为undefined时,它将被重定向。我需要获取此userPermissions对象,但React的“双重呈现"阻止我按需执行逻辑。
有没有办法“加载”userPermissions对象并将其设置为useState挂接而不触发“双重呈现”?

bfnvny8b

bfnvny8b1#

对我来说,将它合并到一个useEffect中似乎是最合理的,但这在代码的整个上下文中可能没有意义。

const [userPermissions, setUserPermissions] = useState();

//Use GET from myService to save to state
useEffect(() => {
  myService.canUserAccess(userId)
  .then(({userPermissions}) => {
    if(!userPermissions){ redirect(...)}
    setUserPermissions(userPermissions)
  });
});
mspsb9vt

mspsb9vt2#

你能存储另一个状态片段来知道它是否加载了吗?

const [gettingUserPermissions, setGettingUserPermissions] = useState(true)

useEffect(() => {
  if(gettingUserPermissions){
    return; // wait until fully loaded
  }
  console.log(userPermissions); //This is the output
  if(!userPermissions){ redirect(...)}
},[gettingUserPermissions, userPermissions, redirect]);

不知道你是如何调用获取用户权限的初始加载的,但我相信这是可以适应的。

slhcrj9b

slhcrj9b3#

您可以实作额外的状态,以检查是否已解析异步函式(myService)的承诺。这会略过userPermissions状态不需要的undefined结果。

const [userPermissions, setUserPermissions] = useState();
const [resolved, isResolved] = useState(false);

useEffect(() => {
  (async () => {
    const userPermissions = await myService.canUserAccess(userId);
    setUserPermissions({ userPermissions });
    isResolved(true);
  })();
}, [myService]);

useEffect(() => {
  if (resolved) {
    if (!userPermissions) {
      redirect(...)
    }
  }
}, [resolved, userPermissions, redirect]);

相关问题