更新嵌套对象时不重新渲染 UseState [英] UseState not re-rendering when updating nested object

查看:43
本文介绍了更新嵌套对象时不重新渲染 UseState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm updating in useEffect by pushing data to the old state object and return it as a value.

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

This code is actually changing the _series variable from useState(), yet no re-rendering takes place, why?

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"时犯了一个错误,所以我尝试一次更新对象的多个部分.这是不好的做法吗?

I might also have done a mistake by updating the key "i" inside the state, so I try to update multiple parts of the object at once. Is this bad practice?

推荐答案

问题在于,当您通过修改原始状态来更改状态时,它的值会在原始引用处更新,因此 React 认为没有任何更改,因此它不会不重新渲染,这就是为什么当您尝试更新状态时期望将状态视为不可变的原因

The problem is that when you change the state by modifying original state its value is updated at the original reference and hence react thinks that nothing has changed and hence it doesn't re-render, that is why it is expected that treat state as if it is immutable when you try to update state

 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" />

这篇关于更新嵌套对象时不重新渲染 UseState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆