反应不渲染来自useEffect的数据

时间:2019-05-21 02:06:52

标签: javascript reactjs react-hooks

我正在尝试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语句中验证了数据。

1 个答案:

答案 0 :(得分:3)

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

React基本上是在执行currentState === newStateFromSetState,因为它是与object相同的引用,因此返回true。

您需要像这样将新对象传递给setData

setData({ ...data });

这将确保传递给object的{​​{1}}是不相同的setData,但是最好构造一个新的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)