首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个useState值的React效果依赖关系和效果重燃

两个useState值的React效果依赖关系和效果重燃
EN

Stack Overflow用户
提问于 2020-07-02 06:22:39
回答 1查看 38关注 0票数 0

以下是我的代码

代码语言:javascript
复制
    const [accountUsers, setAccountUsers] = useState([]);
    const [listLoading, setListLoading] = useState(true);
    const [totalAccountUsers, setTotalAccountUsers] = useState(0);

    const getAccountUserList = useCallback(
        async (page = 0, pageSize = 10) => {
            console.log('Kitne users hain??==', accountUsers.length);
            if (
                // TODO: Move this logic to action for reusability
                accountUsers.length < (page + 1) * pageSize &&
                (accountUsers.length < totalAccountUsers || accountUsers.length === 0)
            ) {
                console.log('inside if condition');

                console.log(' Total Account users=', totalAccountUsers);
                console.log(
                    'first condiont=',
                    ' accountUsers.length < (page + 1) * pageSize ',
                    accountUsers.length < (page + 1) * pageSize,
                    ' AND'
                );
                console.log(
                    'second one condition',
                    ' accountUsers.length < totalAccountUsers =',
                    accountUsers.length < totalAccountUsers,
                    ' OR ',
                    'second two condition',
                    '  accountUsers.length === 0',
                    accountUsers.length === 0
                );

                setListLoading(true);
                const data = await getAccountUsers(id, page + 1, pageSize);
                setAccountUsers((users) => users.concat(data.data.data.results));
                setTotalAccountUsers(data.data.data.total);
                setListLoading(false);
            }
        },
        [accountUsers, totalAccountUsers, id]
    );

    const refetchUsers = useCallback(() => {
        setAccountUsers([]);
        setTotalAccountUsers(0);
    }, []);

    useEffect(() => {
        getAccountUserList();
    }, [getAccountUserList]);


    return (
      <>
         <Button onClick={() => refetchUsers()}>Refetch</Button>
         <Button onClick={async ()=> await delete(id); refetchUsers()> Delete </Button> 
      </>
    )

当单独调用时,我的refetch函数工作正常。但是当涉及异步函数时,回调被调用两次。我感觉在refetch函数中,两个setStates在effect的帮助下导致它调用回调twices。

为什么会发生这种情况,周围的工作是什么?如果在任何异步操作之前调用refetch,那么它可以很好地工作。在触发效果之前react批量处理状态更新会有什么问题吗?

EN

回答 1

Stack Overflow用户

发布于 2020-07-03 04:29:54

通过压缩依赖树(并忽略一些不相关的东西),您的代码可以有效地如下所示:

代码语言:javascript
复制
const Home = () => {
  const [accountUsers, setAccountUsers] = useState<number[]>([]);
  const [totalAccountUsers, setTotalAccountUsers] = useState(0);

  React.useEffect(() => {
    const getAccountUserList = async () => {
      const data = await Promise.resolve({results: [1, 2, 3]});
      setAccountUsers((users) => users.concat(data.results));
      setTotalAccountUsers(data.results.length);
    };

    getAccountUserList();
  },
  [accountUsers, totalAccountUsers]);

  const refetchUsers = () => {
    setAccountUsers([]);
    setTotalAccountUsers(0);
  };

  return (
    <>
       <button onClick={() => refetchUsers()}>Refetch</button>
    </>
  );
};

我们可以很容易地在这里发现这个问题--由useEffect钩子引起的无限重现。您可以看到api可能被调用了两次,因为(幸运的是)它已经完成了所有数据的读取,并且代码中的if条件停止了进一步的状态更新。

一些个人建议:

  1. 从一开始就避免使用useCallback。这是一个优化,我们应该从正确的核心功能开始,而不是optimization.
  2. For用户事件,尽量避免使用useEffect触发副作用-它可能需要额外的状态更新,并导致不必要的重新渲染。直接在事件处理程序中执行此操作。
  3. 使用useEffect进行初始数据加载,而不使用依赖项(只有一次)。
  4. 尝试避免依赖“层次结构”-例如,在最初的情况下,useEffect依赖于依赖于其他状态对象的getAccountUserList。这种层次结构使阅读代码变得更加困难,并可能导致难以发现的错误。相反,请尝试构建代码结构,以便它们直接依赖于状态。

下面的代码(同样,经过简化)应该适用于您的场景:

代码语言:javascript
复制
const Home = () => {
  const [accountUsers, setAccountUsers] = useState<number[]>([]);
  const [totalAccountUsers, setTotalAccountUsers] = useState(0);

  const getAccountUserList = async () => {
    const data = await Promise.resolve({results: [1, 2, 3]});
    setAccountUsers((users) => users.concat(data.results));
    setTotalAccountUsers(data.results.length);
  };

  React.useEffect(() => {
    getAccountUserList();
  }, []);

  const refetchUsers = () => {
    setAccountUsers([]);
    setTotalAccountUsers(0);
    getAccountUserList();
  };

  return (
    <>
       <button onClick={() => refetchUsers()}>Refetch</button>
    </>
  );
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62686188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档