首页  >  问答  >  正文

使用React hooks在复选框组中取消选中多个复选框

<p>我在几个复选框组中运行了几个复选框。我无法弄清楚如何取消选中(从而改变状态)特定的复选框。由于某种原因,我无法访问<code>e.target.checked</code>。</p> <pre class="brush:php;toolbar:false;"><Checkbox size="small" name={item} value={item} checked={checkboxvalues.includes(item)} onChange={(e) => handleOnChange(e)} /></pre> <p>和我的函数</p> <pre class="brush:php;toolbar:false;">const handleOnChange = (e) => { const check = e.target.checked; setChecked(!check); };</pre> <p>我在<strong>这个sandbox</strong>中制作了一个可工作的组件示例。</p>
P粉008829791P粉008829791388 天前406

全部回复(2)我来回复

  • P粉322319601

    P粉3223196012023-08-31 09:00:43

    这是我如何做的:https://codesandbox.io/s/elastic-pateu-flwqvp?file=/components/Selectors.js

    我将选择逻辑抽象成了一个useSelection()自定义钩子,这意味着当前选择可以在store[key].selected中找到,其中key可以是selectors的任何键。

    每个useSelection()调用中的itemsselectedsetSelectedsectionLabel都存储在store[key]中,并传递给一个<CustomCheckboxGroup />组件。

    相关部分是该组件内的handleCheck函数,它根据先前选择的值设置新的选择:如果当前item包含在先前的selected值中,则将其移除。否则,将其添加。


    更详细的解释(为什么)

    仔细观察你的代码,似乎你对React中的复选框组件的工作原理感到困惑。

    inputchecked属性由一个boolean状态控制。通用示例:

    const Checkbox = ({ label }) => {
      const [checked, setChecked] = useState(false)
      return (
        <label>
          <input
            type="checkbox"
            checked={checked}
            onChange={() => setChecked(!checked)}
          />
          <span>{label}</span>
        </label>
      )
    }
    

    在每次渲染时,<input />checked值根据checked状态的当前值设置。当输入的checked发生变化(用户交互时),状态不会自动更新。但是onChange事件被触发,我们使用它来将状态更新为状态先前值的负值。


    当处理<CheckboxList />组件时,我们不能使用单个布尔值来控制所有复选框,我们需要为正在渲染的每个复选框设置一个布尔值。因此,我们创建一个selected数组,并将每个<input />checked值设置为selected.includes(item)的值(返回一个boolean)。

    为了使其工作,我们需要在每个onChange事件中更新selected数组的值。我们检查item是否包含在先前版本的selected中。如果存在,则将其过滤掉。如果不存在,则将其添加进去:

    const CheckboxList = ({ items }) => {
      const [selected, setSelected] = useState([])
      const onChecked = (item) =>
        setSelected((prev) =>
          prev.includes(item)
            ? prev.filter((val) => val !== item)
            : [...prev, item]
        )
    
      return items.map((item) => (
        <label key={item}>
          <input
            type="checkbox"
            checked={selected.includes(item)}
            onChange={() => onChecked(item)}
          />
          <span>{item}</span>
        </label>
      ))
    }
    

    希望这能解决一些问题。

    回复
    0
  • P粉060528326

    P粉0605283262023-08-31 00:36:19

    您需要为每个组创建特定的handleOnChange函数。我已经为Genre复选框组创建了一个类似的函数,您可以按照相同的方式为其他组创建。

    这是处理函数。

    const handleOnChangeGenre = (e) => {
        let newValArr = [];
        if (e.target.checked) {
          newValArr = [...state.pillarGenre.split(","), e.target.value];
        } else {
          newValArr = state.pillarGenre
            .split(",")
            .filter((theGenre) => theGenre.trim() !== e.target.value);
        }
        setState({ ...state, pillarGenre: newValArr.join(",") });
      };

    将此函数作为handleOnChange属性传递给CustomCheckboxGroup,如下所示。

    <CustomCheckboxGroup
              checkboxdata={genres}
              checkboxvalues={state.pillarGenre}
              value={state.pillarGenre}
              sectionlabel="Genre"
              onToggleChange={handleGenreSwitch}
              togglechecked={genreswitch}
              handleOnChange={handleOnChangeGenre}
            />

    为了测试,请注释掉您的handleOnChange函数。

    在沙箱中查看完整的工作解决方案 - 完整代码

    回复
    0
  • 取消回复