reactjs 如何在同步处理useEffect的情况下在React中添加加载状态

pokxtpni  于 2023-02-15  发布在  React
关注(0)|答案(3)|浏览(172)

我有一个应用程序,其中有2个值,用户可以更改,存储为状态。当它们被更改时,我会在useEffect中进行一些处理,并将此处理的输出存储在状态中,然后进行渲染。
此时,一切正常,但此处理需要一些时间,我希望显示一些加载指示器。我希望它在单击按钮后显示。
这是我的应用程序的简化版本和这个加载指示器的哑实现-我知道为什么这不工作,我只是不知道如何正确地写它,所以我这样做只是为了显示我正在尝试做什么。

function App() {
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);
  const [output, setOutput] = useState(0);
  const [isLoading, setIsLoading] = useState(false); // setting true here won't work,
  // because I want to show loading indicator after user change value1 or value2
  // and not on inital load

  useEffect(() => {
    if (!value1 && !value2) {
      return;
    }
    setIsLoading(true);
    for (let i = 0; i < 1999999999; i++) {} // some long operations
    setOutput(value1 + value2);
    setIsLoading(false);
  }, [value1, value2]);

  return (
    <div>
      <button onClick={() => setValue1(value1 + 1)}>increment value1</button>
      <button onClick={() => setValue2(value2 + 1)}>increment value2</button>
      <div>
        {value1} + {value2} = {isLoading ? 'please wait...' : output}
      </div>
    </div>
  );
}
q9yhzks0

q9yhzks01#

您可以将isLoading的值设置为true,这样,页面将在加载时启动。

function App() {
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);
  const [output, setOutput] = useState();
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    for (let i = 0; i < 1999999999; i++) {} // some long operations
    setOutput(value1 + value2);
    setIsLoading(false);
  }, [value1, value2]);

  return (
    <div>
      <button onClick={() => setValue1(value1 + 1)}>increment value1</button>
      <button onClick={() => setValue2(value2 + 1)}>increment value2</button>
      <div>
        {value1} + {value2} = {isLoading ? 'please wait...' : output}
      </div>
    </div>
  );
}
7cwmlq89

7cwmlq892#

试试下面这段代码:

<div>
  <button
    onClick={() => {
      setIsLoading(true);
      setValue1(value1 + 1);
    }}
  >
    increment value1
  </button>
  <button
    onClick={() => {
      setIsLoading(true);
      setValue2(value2 + 1);
    }}
  >
    increment value2
  </button>

完整的代码在这里:https://codesandbox.io/s/relaxed-hill-jy1bfm?file=/src/App.js:689-1018

mwkjh3gx

mwkjh3gx3#

问题是它是异步的。可能有很多不同的解决方法,但对于你的简单例子,我有一个简单的解决方案:

export default function App() {
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);
  const [output, setOutput] = useState(0);
  const isLoading = value1 + value2 !== output;

  useEffect(() => {
    if (!value1 && !value2) {
      return;
    }

    for (let i = 0; i < 1000; i++) {
      console.log(1);
    } // some long operations
    setOutput(value1 + value2);
  }, [value1, value2]);

  return (
    <div>
      <button onClick={() => setValue1(value1 + 1)}>increment value1</button>
      <button onClick={() => setValue2(value2 + 1)}>increment value2</button>
      <div>
        {value1} + {value2} = {isLoading ? "please wait..." : output}
      </div>
    </div>
  );
}

相关问题