复选框未选中reactjs

checkbox is not checked reactjs

我有一个复选框。如果选中该复选框,则应选中表单检查。但这对我不起作用。我有以下代码:

import React, { useState } from 'react'
import { Row, Form, Container } from 'react-bootstrap'
import subMenu from '../subMenu.js'

function TestScreen() {
const [test1, setTest1] = useState(subMenu)
const subMenuHandler = (e) => {
    let sMenu = test1
    sMenu.forEach(sm => {
        if (sm._id === Number(e.target.value))
            sm.isChecked = e.target.checked
    })
    setTest1(sMenu)
}

这是我的表格:

return (
    <Container fluid>
        <Row className="mx-xs-auto">
            <Form>
                <div key='default-checkbox' className="mb-3" >
                    {test1.map(sm => (
                        <Form.Check
                            type="checkbox"
                            id={sm._id}
                            label={sm.nama}
                            key={sm._id}
                            value={sm._id}
                            checked={sm.isChecked}
                            onChange={subMenuHandler}
                        />
                    ))}
                </div>
            </Form>
        </Row>
    </Container >
)

stat isChecked 已成功更改为 true,但 formcheck 未更改为已检查,

这是我的数据:

const subMenu = [
{
    _id: 1,
    nama: 'submenu-1',
    category: 'Electronics',
    harga: 89.99,
    id_menu: 1,
    isChecked: false
},
{
    _id: 2,
    nama: 'submenu-2',
    category: 'Electronics',
    harga: 89.99,
    id_menu: 1,
    isChecked: false
},
{
    _id: 3,
    nama: 'submenu-3',
    harga: 599.99,
    id_menu: 2,
    isChecked: false
},

]

在状态isChecked 已经变为true,那么我哪里错了?我不理解...

而不是 let sMenu = test1,做 let sMenu = [...test1]

在更新状态之前复制您的状态,以便 React 可以检测到新的对象引用可用于触发重新渲染。

在早期的方法中,您只是使用不同的变量名称指向同一个对象(数组也是一个对象)。

在深入研究任何 UI 框架之前,还要对 JS 中的 primitivesnon-primitives 有更多的了解。另一个重要的概念是 shallow vs deep copying 当涉及到对象时。

要在 React 中正确更新状态,您应该为您正在修改的每个部分创建一个副本,而不是直接改变。当您执行 let sMenu = test1 时,您传递的是相同的引用而不是创建副本。

您不仅应该复制数组,还应该复制想要更改的对象。对于真正嵌套的对象,这可能会有点混乱,您会发现自己创建了很多副本。

下面是一种不会改变您的状态片段的方法:

const subMenuHandler = (e) => {

    setTest1(sMenu => (
      sMenu.map(sm => {
        if (sm._id === Number(e.target.value)) return sm
        return { ...sm, isChecked: e.target.checked } 
      })
    ))
}

需要注意的几点:

  • 您创建了要更新的对象的副本 sm。你不要像 sm.isChecked = e.target.checked;

    那样直接改变它
  • 如果您使用的是 Map,则无需在此处对数组使用扩展运算符,因为它已经 returns 一个新数组,而且它不需要变异任何东西。如果您使用扩展运算符也可以,但您会创建另一个在这种情况下不需要的交互。如果您的以下逻辑会改变对象本身,则传播运算符很好。