【问题标题】:How to call an API after setting state successfully?设置状态成功后如何调用API?
【发布时间】:2021-08-29 02:25:36
【问题描述】:
const { Button } = require("@material-ui/core");
const { useState } = require("react");

const Test = () => {
  const [loading, setLoading] = useState(false);

  const [todos, setTodos] = useState([]);
  const [users, setUsers] = useState([]);

  const getTodos = async () => {
    setLoading(true);
    const res = await fetch("https://jsonplaceholder.typicode.com/todos");
    const resData = await res.json();
    setTodos(resData);
    setLoading(false);
  };
  const getUsers = async () => {
    setTodos([]);
    setLoading(true);
    console.log(loading)
    const res = await fetch("https://jsonplaceholder.typicode.com/users");
    const resData = await res.json();
    setUsers(resData);
    setLoading(false);
  };

  return (
    <div>
      <Button
        color="primary"
        variant="contained"
        disabled={loading}
        onClick={getTodos}
      >
        Get Todos
      </Button>
      <Button
        color="primary"
        variant="contained"
        disabled={loading}
        onClick={getUsers}
      >
        Get Users
      </Button>
      {todos.map((item) => (
        <div>{JSON.stringify(item)}</div>
      ))}
      {users.map((item) => (
        <div>{JSON.stringify(item)}</div>
      ))}
    </div>
  );
};

export default Test;


由于 setLoading 是异步的并且不返回任何承诺,有没有办法成功设置加载状态,然后最终获取数据不使用具有加载依赖关系的 useEffect。我认为加载状态使用 useEffect 会变得复杂,因为加载状态用于多个 api 调用。

【问题讨论】:

  • 我看不出当前的实现是如何工作的。你可以先setLoading 再打电话给getUsers
  • 如果我们以getTodos() 为例,setLoading(true)fetch() 可能会被异步调用,而不是一个接一个地调用。我实际上希望它是同步的。
  • 您所做的是正确的,您只需将待办事项设置为response 并在获取后加载到false,设置状态为async,但不应该在您的情况下造成问题。如果你想在设置完待办事项后设置加载,你将不得不使用useEffect,但是你的代码看起来不错。
  • 所以如果setLoading() 需要时间,用户将能够在组件重新渲染之前多次单击该按钮。我有点不希望这种情况发生。
  • 这能回答你的问题吗? How to use `setState` callback on react hooks

标签: reactjs react-hooks


【解决方案1】:

或者你可以尝试这样实现。

import "./styles.css";

const { Button } = require("@material-ui/core");
const { useState } = require("react");

const Test = () => {
  const [loading, setLoading] = useState(false);

  const [todos, setTodos] = useState([]);
  const [users, setUsers] = useState([]);

  // const getTodos = async () => {
  //   setLoading(true);
  //   const res = await fetch("https://jsonplaceholder.typicode.com/todos");
  //   const resData = await res.json();
  //   setTodos(resData);
  //   setLoading(false);
  // };
  // const getUsers = async () => {
  //   setTodos([]);
  //   setLoading(true);
  //   console.log(loading);
  //   const res = await fetch("https://jsonplaceholder.typicode.com/users");
  //   const resData = await res.json();
  //   setUsers(resData);
  //   setLoading(false);
  // };

  const getTodos = () => {
    setLoading(true);

    const getTodosData = async () => {
      const res = await fetch("https://jsonplaceholder.typicode.com/todos");
      const resData = await res.json();
      setTodos(resData);
      setLoading(false);
    };

    getTodosData();
  };

  const getUsers = () => {
    setTodos([]);
    setLoading(true);
    console.log(loading);

    const getUsersData = async () => {
      const res = await fetch("https://jsonplaceholder.typicode.com/users");
      const resData = await res.json();
      setUsers(resData);
      setLoading(false);
    };

    getUsersData();
  };

  return (
    <div>
      <Button
        color="primary"
        variant="contained"
        disabled={loading}
        onClick={getTodos}
      >
        Get Todos
      </Button>
      <Button
        color="primary"
        variant="contained"
        disabled={loading}
        onClick={getUsers}
      >
        Get Users
      </Button>
      {todos.map((item) => (
        <div>{JSON.stringify(item)}</div>
      ))}
      {users.map((item) => (
        <div>{JSON.stringify(item)}</div>
      ))}
    </div>
  );
};

export default Test;

【讨论】:

  • 那会有什么不同吗?例如,如果我们查看 getTodos()setLoading(true)getTodosData() 仍然可能被异步调用,而不是一个接一个地调用
  • @auditore 没有区别,这只是将其委托给不同的功能。您当前的代码没有问题。
猜你喜欢
  • 2018-02-09
  • 2022-11-06
  • 1970-01-01
  • 2019-08-09
  • 2021-05-16
  • 2022-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多