首页 > 解决方案 > 为什么我的承诺没有正确设置我的状态?

问题描述

我有一个调用我的 Rails 后端的 React 前端,我正在尝试编写一个在此执行的 Promise。但是,我不明白我写的承诺有什么问题。我可以看到后端响应正常,但是我无法将组件的状态设置为我正在检索的数据

const [things, setThings] = useState([])

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

function getThingsPromise(){
    return new Promise((resolve, reject) => {
        const url = "/api/v1/things/index";
        fetch(url).then(response => {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Network response was not ok.');
        }).then(response => resolve(response))
    })
}

function fetchThings() {
    getThingsPromise().then((response) => {
        setThings(response)
    })
    console.log(things)
}

标签: ruby-on-railsreactjs

解决方案


您实际上没有设置数据的问题,您只是将 console.log 放在错误的位置。
在反应中设置状态是异步发生的。在您记录您的状态时,它尚未使用收到的数据进行更新。它将在下次组件重新呈现时可用,但是您的 fetchThings() 函数没有被执行,因此您看不到日志。
如果您将 console.log 放在组件主体中,您可以观察到这一点:
在第一次渲染时,它会记录仍然为空的状态,然后在接收到数据后状态会更新,这会导致组件重新渲染。在第二次渲染中,数据将可用。

function App() {
  const [things, setThings] = useState([]);

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

  function getThingsPromise() {
    return new Promise((resolve, reject) => {
      const url = "/api/v1/things/index";
      fetch(url)
        .then(response => {
          if (response.ok) {
            return response.json();
          }
          throw new Error("Network response was not ok.");
        })
        .then(response => resolve(response));
    });
  }

  function fetchThings() {
    getThingsPromise().then(response => {
      setThings(response);
    });
    console.log("The state hasn't been updated yet:", things);
  }

  // this logs the state every time the component renders
  console.log("First it's empty, then we have data:", things);

  return <div>result: {JSON.stringify(things)}</div>;
}

你可以在这里工作的例子: https ://codesandbox.io/s/hooks-setstate-log-hjle1?fontsize=14


推荐阅读