【问题标题】:UseState not re-rendering when updating nested object更新嵌套对象时 UseState 不重新渲染
【发布时间】:2019-05-08 03:37:42
【问题描述】:

我通过将数据推送到旧状态对象并将其作为值返回来更新 useEffect。

这段代码实际上是从 useState() 改变了 _series 变量,但是没有重新渲染,为什么?

import { TimeSeries, Pipeline, Stream, EventOut, TimeEvent, TimeRange  } from "pondjs";

export default () => {

  const [_series, $series] = useState(()=>{
    let state = { data : { "name": "x", "columns": ["time", "value"], "points": [], "i" : 0}}
    for(let i=10; i >= 0; i--){state.data.points.push( [new Date(i)-(i*100), Math.round(Math.random()*100)])}
    return state;
  })

  useEffect(() => {
    const interval = setInterval(() => {
      $series(s => {
        s.data.points.push( [new Date(s.data.i*1000), Math.round(Math.sin(s.data.i/10)*50+50)] )
        s.data.points.shift();
        s.data.i++;
        return s;
      });
    }, 500);
  }, []);


    return(
    <p>{

          JSON.stringify((new TimeSeries(_series.data)).collection())

    }</p>
    )

}


我也可能通过更新状态中的键“i”而犯了一个错误,所以我尝试一次更新对象的多个部分。这是不好的做法吗?

【问题讨论】:

  • return {...s} 会创建一个新对象以确保 React 知道它是一个新状态

标签: reactjs react-hooks


【解决方案1】:

问题在于,当您通过修改原始状态来更改状态时,它的值会在原始引用处更新,因此 react 认为没有任何变化,因此不会重新渲染,这就是为什么预计会处理当您尝试更新状态时,状态好像它是不可变的

 const { useState, useEffect } = React;
 const App = () => {
    
      const [_series, $series] = useState(()=>{
        let state = { data : { "name": "x", "columns": ["time", "value"], "points": [], "i" : 0}}
        for(let i=10; i >= 0; i--){state.data.points.push( [new Date(i)-(i*100), Math.round(Math.random()*100)])}
        return state;
      })
    
      useEffect(() => {
        const interval = setInterval(() => {
          $series(s => {
            return {
                ...s,
                data: {
                  ...s.data,
                  i: s.data.i + 1,
                  points: [...s.data.points.slice(1), [new Date(s.data.i*1000), Math.round(Math.sin(s.data.i/10)*50+50)]]
                }
            }
          });
        }, 500);
      }, []);
    
    
        return(
        <p>{
    
              JSON.stringify(_series.data)
    
        }</p>
        )
    
    }
    
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 2021-04-13
    • 1970-01-01
    • 2021-03-10
    • 2021-03-24
    • 2021-07-15
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多