首页 > 解决方案 > 反应不渲染来自 useEffect 的数据

问题描述

我正在尝试 React 钩子,但我对所看到的内容感到非常困惑。我从我的端点获取一个 JS 对象作为有效负载,如果我传递原始结果,这将很好地显示和渲染:

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

const Status = () => {
  const [data, setData] = useState({})

  useEffect(() => {
    console.log('fetching status')
    const start = new Date()
    getStatus()
    .then(result => {
      console.log(`status fetched in ${(new Date() - start)}`)
      for (const key of Object.keys(result)) {
        if (!data[key]) {
          data[key] = {}
        }
        data[key]['status'] = result[key]
      }
      console.log(data);
      setData(result)
    })
    .catch(err => console.error(err))
  }, [])
  return (
    <div>
      { console.log('rendering')}
      <h1>Status</h1>
      <span>{JSON.stringify(data)}</span>
    </div>
  )
}

export default Status

...并且我得到了两个“渲染”日志,正如预期的那样。

但是当我将其更改为实际使用处理后的数据时:

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

const Status = () => {
  const [data, setData] = useState({})

  useEffect(() => {
    console.log('fetching status')
    const start = new Date()
    getStatus()
    .then(result => {
      console.log(`status fetched in ${(new Date() - start)}`)
      for (const key of Object.keys(result)) {
        if (!data[key]) {
          data[key] = {}
        }
        data[key]['status'] = result[key]
      }
      console.log(data);
      setData(data) // <--- here
    })
    .catch(err => console.error(err))
  }, [])
  return (
    <div>
      { console.log('rendering')}
      <h1>Status</h1>
      <span>{JSON.stringify(data)}</span>
    </div>
  )
}

export default Status

我没有得到第二次渲染,信息也没有在页面上呈现。正如我在 console.log 语句中验证的那样,数据就在那里。

标签: javascriptreactjsreact-hooks

解决方案


原因是你传递了同一个对象,setData因为它是同一个对象,所以不会导致重新渲染。

React基本上是这样做currentState === newStateFromSetState的,这将返回 true,因为它是相同的object引用。

你需要传递一个新对象来setData喜欢这个

setData({ ...data });

这将确保object传递给setData的 a 不一样object,但最好只构造一个新的object而不是改变当前的。

const updatedData = { ...data }

for (const key of Object.keys(result)) {
  if (!updatedData[key]) {
    updatedData[key] = {}
  }
  updatedData[key]['status'] = result[key]
}

console.log(data)
setData(updatedData)

推荐阅读