无法通过 React 以编程方式重置复选框 Bootstrap

Having trouble getting checkboxes to programmatically reset with React Bootstrap

我找到了以编程方式重置复选框列表中的选项的解决方案,但是,由于某种原因,图形元素本身不会更改以匹配状态。我以为它会在状态更改时自动执行它,但是,除了我目前正在做的事情之外,似乎还必须有一种我应该单独执行它的方法。

首先,我初始化复选框选项:

const [categoryFilterOptions, setCategoryFilterOptions] = useState([{label: 'Category1', checked: true}, {label: 'Category2', checked: true}, {label: 'Category3', checked: true}, {label: 'Category4', checked: true}])

这会在渲染时传递到我的清单组件并像这样处理:

 {checks.map((checkItem, i) => (
                 <Form.Check
                    key={i}
                    id={i}
                    type='checkbox'
                    label={checkItem.label}
                    defaultChecked={checkItem.checked}
                    onClick={() => {setCheck(i)}}
                ></Form.Check>
            )) }

然后要重置它们,我有一个按钮:

<Button style={{width: '100%'}} onClick={() => {resetAllChecks()}}>Reset Filter</Button>

调用方法 resetAllChecks() 将我的检查选项设置回初始状态:

const resetAllChecks = () => {
    setFamilyFilterOptions([{label: 'String', checked: true}, {label: 'Percussion', checked: true}, {label: 'Brass', checked: true}, {label: 'Wind', checked: true}, {label: 'Electronic', checked: true}, {label: 'Keyboard', checked: true}])
    setCategoryFilterOptions([{label: 'Contemporary', checked: true}, {label: 'Orchestral', checked: true}, {label: 'Traditional', checked: true}, {label: 'Vocal', checked: true}])
}

我真的不确定为什么它拒绝重置复选框的图形元素,因为列表被重置得很好,但复选框却没有。

编辑: 下面是一些周边的代码,可能上下文比较好?

从编程上讲,它在数据方面工作得很好,只是图形没有更新,所以我不确定这是否会有很大帮助,但值得一试!

const DropdownChecklist = ({disabled, checkOptions, returnChecksState}) => {
    const [checks, setChecks] = useState([...checkOptions]); 

    function setCheck(id){
        var newArray = [...checks]
        var newElement = checks[id];
        newElement.checked = (!newElement.checked)
        newArray[id] = newElement;
        setChecks(newArray);
        returnChecksState(checks);
    }

    console.log(checks)
    
    return (
        <Form className={styles.checkMenu}>
            <fieldset disabled={disabled}>
            {checks.map((checkItem, i) => (
                <Form.Check
                    key={i}
                    id={i}
                    type='checkbox'
                    label={checkItem.label}
                    checked={checkItem.checked}
                    onChange={() => {setCheck(i)}}
                ></Form.Check>
            )) }
            </fieldset>
        </Form>
    )
}

export default DropdownChecklist

编辑 2:更多上下文

<Col>
     <h5 style={{textAlign: 'center', color: 'white'}}>Category Filtering: </h5>
     <DropdownChecklist disabled={false} checkOptions={categoryFilterOptions} returnChecksState={setCategoryFilterOptions}></DropdownChecklist>
 </Col>

编辑 3: 我尝试使用提供的解决方案 Here,但它仍然无法正常工作,但是,我现在意识到,不知何故,我正在重置我的检查的组件逻辑以某种方式直接触及我的 DEFAULT_CHECKS 值,这是没有意义的对我来说,特别是因为它是一个 const 值,甚至不应该改变

defaultChecked 属性只能与 uncontrolled components 一起使用,在大多数情况下您不需要。您看到的行为是预期的:

Changing the value of defaultValue attribute after a component has mounted will not cause any update of the value in the DOM.

当您想要以编程方式操作您的输入值时,您通常应该更喜欢 controlled components。这个想法是输入应该总是从 React 的状态中获取它的值,并且与输入的交互应该相应地更新状态。

对于复选框,这意味着设置 checkedonChange 道具,所以它看起来像:

{checks.map((checkItem, i) => (
    <Form.Check
        key={i}
        id={i}
        type='checkbox'
        label={checkItem.label}
        checked={checkItem.checked}
        onChange={() => {setCheck(i)}}
    ></Form.Check>
)) }

现在,当您调用 resetAllChecks() 时,复选框应该 re-render 具有状态中的最新值。

您不应尝试同时更改父状态和子状态。让父级处理更改并将它们传递给新道具。

import React, { useState } from 'react';
import { Col, Form, Button } from 'react-bootstrap';

export default function App() {
  const [categoryFilterOptions, setCategoryFilterOptions] = useState([
    { label: 'Category1', checked: true },
    { label: 'Category2', checked: true },
    { label: 'Category3', checked: true },
    { label: 'Category4', checked: true },
  ]);

  const resetAllChecks = () => {
    setCategoryFilterOptions(
      categoryFilterOptions.map((option) => ({
        label: option.label,
        checked: true,
      }))
    );
  };

  return (
    <Col>
      <h5 style={{ textAlign: 'center', color: 'black' }}>
        Category Filtering:
      </h5>
      <DropdownChecklist
        disabled={false}
        checkOptions={categoryFilterOptions}
        returnChecksState={setCategoryFilterOptions}
      ></DropdownChecklist>
      <Button
        style={{ width: '100%' }}
        onClick={() => {
          resetAllChecks();
        }}
      >
        Reset Filter
      </Button>
    </Col>
  );
}

const DropdownChecklist = ({ disabled, checkOptions, returnChecksState }) => {
  function setCheck(id) {
    var newArray = [...checkOptions];
    var newElement = checkOptions[id];
    newElement.checked = !newElement.checked;
    newArray[id] = newElement;
    returnChecksState(newArray);
  }

  return (
    <Form>
      <fieldset disabled={disabled}>
        {checkOptions.map((checkItem, i) => (
          <Form.Check
            key={checkItem.label}
            id={i}
            type="checkbox"
            label={checkItem.label}
            checked={checkItem.checked}
            onChange={() => {
              setCheck(i);
            }}
          ></Form.Check>
        ))}
      </fieldset>
    </Form>
  );
};

你可以看到一个工作示例here

先生,不要使用不受控制的组件。