react里面 点击一个开关按钮的时候耗时2s才会响应 所以想要一个loading 我useEffect监听的开关绑定的变量 useEffect里面是做的处理 为什么不生效?

1695781680041.png
react里面 点击一个开关按钮的时候耗时2s才会响应 所以想要一个loading 我useEffect监听的开关绑定的变量 useEffect里面是做的处理
但是我在useEffect里面第一行setLoading(true),最后一行setLoading(false),loading没有生效 是为什么?

阅读 967
avatarAI BotBETA

在 React 中,useEffect 的回调函数是异步的,它将在下一次更新周期中执行。因此,如果你在 useEffect 回调函数中直接设置 loadingtruefalse,它可能不会在组件渲染时立即反映出来。

为了解决这个问题,你可以使用 useState 钩子在组件中创建一个 loading 状态,并在 useEffect 回调函数中更新它。同时,你也需要在 useEffect 的依赖数组中添加你监听的变量,以便在监听变量变化时触发回调函数。

以下是一个示例代码:

import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [loading, setLoading] = useState(false);
  const [开关绑定的变量, set开关绑定的变量] = useState(false);

  useEffect(() => {
    setLoading(true);

    // 这里处理需要延迟2秒的逻辑
    setTimeout(() => {
      // 执行完处理后,将 loading 设置为 false
      setLoading(false);
    }, 2000);
  }, [开关绑定的变量]); // 在开关绑定的变量变化时触发 useEffect

  return (
    <div>
      <button onClick={() => set开关绑定的变量(!开关绑定的变量)}>
        开关按钮
      </button>
      {loading ? <div>loading...</div> : null}
    </div>
  );
}

在这个示例中,当点击开关按钮时,useEffect 钩子的回调函数将被触发,设置 loadingtrue。然后,在 2 秒后,将执行一个延迟函数,将 loading 设置为 false。在组件的 JSX 中,根据 loading 的值来决定是否显示加载提示。

3 个回答

是说中间那个 代码段落 耗时特别久吗?应该是同步的,导致状态没有更新。

可以将 setLoading(true) 后面的代码放到一个 setTimeout 中试试,让浏览器和 react 在中间可以多渲染一帧

代码中将 setLoading(true)setLoading(false) 放在 useEffect 中可能会触发 React 的批处理机制,导致 React 将状态合并后再统一渲染。
可以试着将 setLoading(true) 放在触发 setIsJl 状态变更的地方,从而将 setLoading(true)setLoading(false) 分离开来。
希望这个回答有所帮助!

我试着帮你修改了一下代码;
1.用 Map 去替换 some 比较 ,Map 在大数据量查询比较快
2.去除部门数组的获取方式,部因为这里的 map消耗太大了 可以省略 在上面的循环中构建出。

const selecteds = ['1,2,3', '4,5,6', '1,2,1', '2,1,4'];

function getSelecteds(selecteds: string[]): {
  newSelectKeys: string[]; department: {
    id: string;
    organization: string;
    parentId: string;
  }[];
} {
  const newSelectKeys: string[] = [];
  const department = [] as Array<{ id: string, organization: string, parentId: string }>;
  const maps = new Map<string, string>();

  for (let i = 0; i < selecteds.length; i++) {
    const key = selecteds[i].split(',')[2];
    maps.set(key, selecteds[i]);
  }

  maps.forEach((value) => {
    const [id, organization, parentId] = value.split(',');
    if (!maps.has(id)) {
      newSelectKeys.push(value);
      department.push({ id, organization, parentId })
    }
  });
  return { newSelectKeys, department };
}
console.log('res====', getSelecteds(selecteds));

同步代码基本不需要 loading 的,
你试试看看能不能降低运算时间。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题