更新地图内的状态,会导致将新元素推送到我不想要的状态

问题描述 投票:0回答:1

这里我有数据状态,我试图用地图函数循环它,并打印出我称之为 myChecklist 的清单。

import React, { useState } from 'react'

const App = () => {

  const [data, setData] = useState([
    {
      id:0,
      isChecked: true
    },
    {
      id:1,
      isChecked: false
    },
    {
      id:2,
      isChecked: false
    },
  ])
  

  const myCheckList = data.map((checkbox, index) => {
    return (
      <div key={index}>
        <input type="checkbox" 
          checked={checkbox.isChecked} 
          onChange={e => {setData(prev => [...prev, prev[index].isChecked = e.target.checked])}} 
          id={index} />
        <label htmlFor={index}>{checkbox.id}</label>
      </div>
    )
  })

  console.log(data)

  return (
    <div>{myCheckList}</div>
  )
}

export default App

每次单击任何复选框时,它都会更新为 isChecked 引用该复选框的布尔值。问题是将新元素推送到 data 状态,这会导致 map 函数创建一个我不想要的新复选框。当我单击复选框时,**数据 **状态的日志应该如下所示:

[
    {
        "id": 0,
        "isChecked": true
    },
    {
        "id": 1,
        "isChecked": false
    },
    {
        "id": 2,
        "isChecked": false
    }
]

但是在更改复选框几次后,它看起来像这样:

[
    {
        "id": 0,
        "isChecked": true
    },
    {
        "id": 1,
        "isChecked": false
    },
    {
        "id": 2,
        "isChecked": false
    },
    false,
    true
]

注意到一些 true false 值被推送到状态。我没有推动任何事情所以为什么会发生这种情况???

我将感谢您的帮助。谢谢

我尝试将我正在映射的状态与我想要更新的状态分开

import React, { useState } from 'react'

const App = () => {

  const [isChecked, setIsChecked] = useState([
    {isChecked: false},
    {isChecked: false},
    {isChecked: false}
  ])

  const data = [
    {
      id:0,
    },
    {
      id:1,
    },
    {
      id:2,
    },
  ]


  const myCheckList = data.map((checkbox, index) => {
    return (
      <div key={index}>
        <input type="checkbox" 
          checked={isChecked[index].isChecked} 
          onChange={e => {setIsChecked(prev => [...prev, prev[index].isChecked = e.target.checked])}} 
          id={index} />
        <label htmlFor={index}>{checkbox.id}</label>
      </div>
    )
  })

  console.log(isChecked)

  return (
    <div id='my-id'>{myCheckList}</div>
  )
}

export default App```

no new checkboxes would be printed to DOM but the issue of pushing elements I don't to the state, still remains
reactjs react-hooks checkbox array.prototype.map
1个回答
0
投票
[
    {
        "id": 0,
        "isChecked": true
    },
    {
        "id": 1,
        "isChecked": true
    },
    {
        "id": 2,
        "isChecked": false
    }
]

如果您想要这样的输出,则您的代码有问题。特别是这一行

          onChange={e => {setData(prev => [...prev, prev[index].isChecked = e.target.checked])}} 

你在这里做什么是,你正在追加到上一个数组,并且你输入的对象是一个bool(其逻辑是错误的)。

正确的做法是先确定被改变的复选框的索引,然后翻转为

isChecked
值。

这是代码:

import React, { useState } from "react";

const App = () => {
  const [data, setData] = useState([
    {
      id: 0,
      isChecked: true,
    },
    {
      id: 1,
      isChecked: false,
    },
    {
      id: 2,
      isChecked: false,
    },
  ]);
  const handleCheckboxChange = (index) => {
    setData((prev) => {
      return prev.map((checkbox, i) => {
        if (i === index) {
          return {
            ...checkbox,
            isChecked: !checkbox.isChecked,
          };
        }
        return checkbox;
      });
    });
  };

  const myCheckList = data.map((checkbox, index) => {
    return (
      <div key={index}>
        <input
          type="checkbox"
          checked={checkbox.isChecked}
            onChange={() => handleCheckboxChange(index)}
          id={index}
        />
        <label htmlFor={index}>{checkbox.id}</label>
      </div>
    );
  });

  console.log(data);

  return <div>{myCheckList}</div>;
};

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.