我的 useEffect 代码有什么问题,为什么我的状态变量是空的?

What's wrong with my useEffect code, and why is my state variable empty?

我有一个问题,我不确定是什么导致了这个问题。

所以我用外部 api 进行了一次获取,我想打印出 api 中的一些信息。我已经记录了数据和状态变量以查看它们是否 return 数据。我的问题是我没有从控制台的状态变量中获取任何数据。当我在控制台中登录时,它只显示一个空数组。但是当我记录 console.log(data) 时,我在控制台中获得了数据。

当我删除 useEffect 末尾的空数组时,它在控制台中有效,但它是一个无限循环。如果我将状态变量放在空数组中,也会发生同样的事情。

有人知道问题出在哪里吗?

export const Communication = () => {
  const [article, setArticle] = useState([])

  useEffect(() => {
    fetch('https://cors-anywhere.herokuapp.com/https://api.fortnox.se/3/articles', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Access-Token': accessToken,
        'Client-Secret': clientSecret
      }
    })
      .then((res) => res.json())
      .then((data) => {
        setArticle(data)

        console.log('json', data)
        console.log('article', article)
      })
  }, [])

想想 JavaScript 是如何运作的。使用此语句,您声明了两个变量:

const [article, setArticle] = useState([])

如果您考虑 article,则任何对外部函数的调用都无法将 article 分配给新值。这不仅仅是因为它是 const;即使使用 let ,外部函数也无法更改它;我们没有指针之类的东西。这与这里发生的事情没有什么不同:

function a() {
  let foo = 1;
  changeFoo(2);
}

function changeFoo(newValue) {
  // How do I change `foo` inside of function `a`? Spoiler, I cannot!
}

同样,调用setArticle也没有办法更新文章值。这不是 React 的工作方式。相反,下次您的组件调用 useState 时,它将收到新值。因此这就是为什么:

setArticle(data);
console.log(article);

...将记录 article 的旧值。这并不意味着 setArticle 没有用;这意味着你期望 React 有点太神奇了。 article 将在下一次渲染时对 useState 的下一次调用分配新值。如果你想记录不断变化的文章状态,你会想要做一些更像:

export const Communication = () => {
  const [article, setArticle] = useState([])
  console.log('article', article);

  useEffect(() => {
    fetch('https://cors-anywhere.herokuapp.com/https://api.fortnox.se/3/articles', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Access-Token': accessToken,
        'Client-Secret': clientSecret
      }
    })
      .then((res) => res.json())
      .then(setArticle)
  }, [])

  // ...
}