为什么我的状态会改变而我没有改变它?

时间:2021-07-20 13:10:45

标签: javascript reactjs

我正在学习 React,目前我正在构建一个排序可视化工具,但在调用 sort 方法后我的状态发生了变化。

我将条形数量保存为状态。
我还保存了条形图的副本,该副本不会更改并且仍然拥有旧条形图的价值。

import React, { useState , useEffect } from 'react'
import './App.css';
// importing the bar component
import { Bar } from './Bar'; 
//sort function but i currently don't use it
import boubleSort from './sortFunctions/boublesort';

let localBars = [] // i tried to save a copy of the old bars and this copy doesn't change
     
function App() {

  const [speed , setSpeed] = useState(1000) //speed state
  const [bars , setBars] = useState([]) //bars that i saved as state

 
  // generating random bars this is the only method that can change the bars
  function genrate(size) {

     let array = []
     for(let i=0 ; i<size ; i++)
      {
        let bar = {}
        bar.value = Math.floor(Math.random() * 495) + 5
        bar.color = "crimson"
        array.push(bar)
      }

      
      setBars([...array])
      console.clear()
      console.log(bars) //testing the bars value
      localBars = [...bars] //saving the copy
      console.log(localBars) //testing the copy of bars value
      
  }

  function sizeHandler() {
      const size =  document.getElementById('sizeRange').value //the size of the bars array
// i didn't save size as an state because it was full of bugs
      document.getElementById('size').innerHTML = size //showing the size
      genrate(size) //generating the bars
  }

  function speedHandler() {
     setSpeed(document.getElementById('speedRange').value) //speed handler
  }

  function sort() {
     
    // here the value of bars is difrent from the old bars and the localBars (the copy of bars)
    console.log(bars)
    console.log(localBars)
    
     
  }

  return (
    <div className="App">
        <header className="header">
          <div className="options">
            <button className="gen" onClick={sizeHandler} >genrate</button>
            <button className="sort" onClick={sort} >sort</button>
            <input type="range" min="10" max="200"   class="slider" id="sizeRange" onChange={sizeHandler} />
            <p id="size" >50</p>
            <input type="range" min="1" max="1000"  class="slider" id="speedRange" onChange={speedHandler} />
            <p  id="size" >{speed}</p>
            </div>
        </header>
        //rendering the bars
        <div className="bars-container" id="bars">
          {bars.map(bar => (
           <Bar data={bar} />
          ))}
        </div>
    </div>
  );
}


export default App;

这是我的 bar 组件,它从 bar 对象中获取数据并渲染它

import React from 'react'

export const Bar = ({data}) => {

   //parsing data into extra styles
   let style = {}
   style.backgroundColor = data.color
   style.height = data.value + "px"

    return (
        <div className="bar" style={style}></div>
    )
}

1 个答案:

答案 0 :(得分:0)

这部分代码不清楚:

  setBars([...array])
  console.clear()
  console.log(bars) //testing the bars value
  localBars = [...bars] //saving the copy
  console.log(localBars) //testing the copy of bars value

因此,一开始您将 bars 设置为 array。还行吧。然后你记录 bars (它应该是一个空数组,因为 setBars 是异步的)。然后您将 bars 复制到 localBars (并且这里的 bars 也可能由于异步而为空;但为什么呢?您已经拥有 array,请使用它)。最后,您登录 localBars(同样,由于异步可能为空)。

我建议像这样修改你的代码:

setBars([...array])
console.clear()
console.log(array) //remember here bars could be empty, better print array: will be the next bars value
localBars = [...array] //saving the copy
console.log(localBars) //testing the copy of bars value

好的,现在假设您想打印 bars 值(因为您想确保正确设置 bars)。在这种情况下,在 deps 列表中使用 useEffectbars。类似的东西:

useEffect(() => {
   console.log(bars);
}, [bars])

这样您将看到 bars 的当前值,但请记住,每次 useEffect 更改其值时都会触发此 bars