【问题标题】:React not rendering data from useEffect反应不渲染来自 useEffect 的数据
【发布时间】:2019-10-07 08:52:52
【问题描述】:

我正在尝试 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 语句中验证的那样,数据就在那里。

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

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

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

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

    setData({ ...data });
    

    这将确保传递给setDataobjectobject 不同,但最好只构造一个新的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)
    

    【讨论】:

    • 这肯定不同于状态更新的类版本,因为我已经能够调用this.setState(prev =&gt; { //modify prev and return it },它会导致渲染
    • 我从未尝试过变异并返回 prev,我只是对其进行了测试,它确实有效,我猜当从 this.setState 回调返回某些内容时,react 正在内部做一些事情
    • 不管怎样,这可能是更正确的做法
    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 2015-07-15
    • 2020-09-05
    • 2022-10-25
    • 2019-04-26
    • 1970-01-01
    • 2021-04-16
    • 2021-11-15
    相关资源
    最近更新 更多