【问题标题】:update State react hook JSON data更新状态反应挂钩 JSON 数据
【发布时间】:2026-01-29 17:35:01
【问题描述】:

我正在尝试更新状态(JSON 数据)。 初始状态是一个空对象,因为将在第一次渲染时填充“树”(json 数据)(树数据来自一个承诺,所以我尝试使用 useEffect 来模拟它)。 问题是我不知道如何用每个滑块(target.value)的值更新“tree”中的“val”属性。

import React, {useEffect, useState} from 'react'
import ReactDOM from 'react-dom'
import Slider from './slider'


let data = [
  {id: 'Item 1', index: 0, name: 'Item 1'},
  {id: 'Item 2', index: 1, name: 'Item 2'},
  {id: 'Item 3', index: 2, name: 'Item 3'},
  {id: 'Item 4', index: 3, name: 'Item 4'},
  {id: 'Item 5', index: 5, name: 'Item 5'},
  {id: 'Item 6', index: 6, name: 'Item 6'},
  {id: 'Item 7', index: 7, name: 'Item 7'},
  {id: 'Item 8', index: 9, name: 'Item 8'},
  {id: 'Item 9', index: 12, name: 'Item 9'},
]
let data2 = [
  {id: 1, val: 0.5088961783678},
  {id: 2, val: 0.074147856793482},
  {id: 3, val: 0.074147856793482},
  {id: 5, val: 0.074147856793482},
  {id: 6, val: 0.074147856793482},
  {id: 7, val: 0.074147856793482},
  {id: 0, val: 0.097068824077823},
  {id: 9, val: 0.074147856793482},
  {id: 12, val: 0.074147856793482},
]

function App() {
  const [values, setValues] = useState({})


  function handleChange(index, value) {
    setValues() 
  }

  
  let tree = {}
    data2.forEach((v) => {
      tree[v.id] = (v.val * 100).toFixed()
    })
    

  
  React.useEffect(() =>{
    setValues(tree)
  },[])

    
  return (
    <>
      {data.map((item, index) => (
        <Slider
          key={item.id}
          value={values[item.index]}
          title={item.name}
          onChange={(e) => handleChange(index, e.target.value)}
        />
      ))}
    </>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))

【问题讨论】:

  • 您要显示多个滑块?
  • 我已经通过映射数据数组来做到这一点。
  • 树和数据数组是什么关系?
  • 树中的“val”应该分配给与数据索引匹配的滑块。例如:id:0 的 val 应该分配给索引为 0 的滑块。我已经这样做了

标签: javascript json reactjs react-hooks


【解决方案1】:

你可以像这样更新状态:

function handleChange(index, value) {
  setValues((prevState) => {
     return { ...prevState, ...{[index]: value}};
  });
}

沙盒:https://codesandbox.io/s/frosty-davinci-p5d7k?file=/src/App.js:992-1125

【讨论】:

  • 谢谢哥们。你能帮我修改这个函数吗: function handleChange(index, value) { const remaining = 100 - parseInt(value, 10) setValues((vs) => vs.map((v, i) => { if (i === index) return parseInt(value, 10) const oldRemaining = 100 - parseInt(vs[index], 10) if (oldRemaining) return (remaining * v) / oldRemaining return remaining / (sliders.length - 1) }) , ) } 所以当状态是 json 时这也可以工作?
  • 基本上这个函数是以相等的模式将总值拆分给所有滑块。当一个滑块移动时,其他滑块的值会自动改变(总和最大为 100)。第一次状态是一个数组,所以我可以映射值,但现在它是一个 json,我不知道该怎么做。以下是前面的滑块(带有数组)的示例:codesandbox.io/embed/intelligent-rosalind-0hiyl?file=/src/…
  • 您能以新问题的格式发布此格式吗?如您所见,代码 cmets 非常不可读(完全可以,并且在此站点上鼓励将不同的问题拆分为多个问题)
  • 感谢您的回答。我把它贴在这里作为答案。希望没事
【解决方案2】:

我怎样才能使这个函数与 JSON 一起工作:

const [values, setValues] = useState(
    new Array(sliders.length).fill(100 / sliders.length),
  )

  function handleChange(index, value) {
    const remaining = 100 - parseInt(value, 10)
    setValues((vs) =>
      vs.map((v, i) => {
        if (i === index) return parseInt(value, 10)
        const oldRemaining = 100 - parseInt(vs[index], 10)
        if (oldRemaining) return (remaining * v) / oldRemaining
        return remaining / (sliders.length - 1)
      }),
    )
  }

基本上,此功能以相等的模式将总值拆分给所有滑块。 当一个滑块移动时,其他滑块的值会自动改变(总和最大为 100)。 第一次状态是一个数组,所以我可以映射值,但现在它是一个 json,我不知道该怎么做。

以下是前面的滑块(带有数组)的示例:https://codesandbox.io/embed/intelligent-rosalind-0hiyl?file=/src/index.js&codemirror=1

【讨论】: