繁体   English   中英

如何在 React 中使用 useState 检查复选框的更改值

[英]How change value of checkbox checked using useState in React

我会将带有属性的复选框字段列表传递给我的组件,我想根据人的选择来更改checked属性的值,但我能做的最多是将数组中的检查值加倍。

如何在我的 state 中更改此特定密钥?

这是我的代码:

export default function Combocheck({ data, title, id }) {
  const inputLabel = React.useRef(null);

  const [state, setState] = React.useState({
    checkbox: data.map((element) => {
      element.checked = false;
      return element;
    })
  });

  const changeState = name => event => {
    const newValue = !state.checkbox[name].checked;
    setState({ checkbox: [
        ...state.checkbox,
        state.checkbox[name] = {
          ...state.checkbox[name],
          checked: newValue
        }
      ]
    });
  }

  console.log(state);

  return (
    <div> 
      <Typography color='textSecondary'>{title}</Typography>
      <Divider />
      <FormGroup>
        {state.checkbox.map(({code, description, checked}, i) => {
          return <FormControlLabel control={
            <Checkbox
              key={code}
              checked={checked}
              onChange={changeState(i)}
              value={code}
              color="primary"
            />
          }
          key={code}
          label={description}
          />
        })}
      </FormGroup>
    </div>
  );
}

可以在这里查看或编辑: https://stackblitz.com/edit/react-irhqw9?file=Hello.js

每次更新 state 时,您都会添加一个复选框项目,而是:考虑映射您的元素并仅更改适用的元素:

const changeState = name => event => {
  setState({ 
    checkbox: state.checkbox.map((checkbox, i) => {
      return i !== name ? 
        checkbox : 
        { ...checkbox, checked: !checkbox.checked }
    }) 
  });
}

我也不喜欢使用元素索引作为名称。 我很确定你会很好地使用代码(假设它是唯一的),然后这不需要是更高阶的 function:

const changeState = event => {
  setState({ 
    checkbox: state.checkbox.map((checkbox) => {
      return event.target.value !== checkbox.code ? 
        checkbox : 
        { ...checkbox, checked: !checkbox.checked }
    }) 
  });
}

然后在Checkbox道具中:

onChange={changeState}

我更喜欢为每个复选框使用一个 useState function。

In the 'old days' before hooks, each component had only one state - and the setState function would merge that state with the object passed to setState . Hooks & useState 不会那样做。 您可以在一个组件中拥有多个 useState 挂钩,并且 state 不会合并。

这里有一些代码可以粘贴到使用 create-react-app 创建的 App.js 中来说明我的意思:

应用程序.js

import React, { useState } from 'react';

function App() {
  var [ firstCheckbox, setFirstCheckbox ]   = useState(true); // true - first check box defaults to checked.
  var [ secondCheckbox, setSecondCheckbox ] = useState(false); // false = second check box defaults to un-checked.
  return (
    <div style={{display:'flex', flexDirection: 'column'}}>
        <label for='first-check-box'><input type="checkbox" checked={firstCheckbox} onChange={() => setFirstCheckbox(!firstCheckbox)}></input>First Check Box</label>
        <label for='second-check-box'><input type="checkbox" checked={secondCheckbox} onChange={() => setSecondCheckbox(!secondCheckbox)}></input>Second Check Box</label>
    </div>
  );
}

export default App;

另一个使 chrome 开发者工具更有用的提示:当你按照我的建议使用许多 useState 钩子时,很难看出哪个 state 钩子是哪个。 每个 useState 挂钩只显示为useState: true ,没有任何标签。 以下代码通过使实际 state 成为 object 的属性来标识开发人员工具的“组件”选项卡中的 useState 挂钩,其中键是 label 以显示在 chrome 开发人员工具中。

应用程序.js:

import React, { useState } from 'react';

function App() {
  var [ firstCheckbox, setFirstCheckbox ]   = useState({firstCheckBox: true});
  var [ secondCheckbox, setSecondCheckbox ] = useState({secondCheckBox: false});
  return (
    <div style={{display:'flex', flexDirection: 'column'}}>
        <label htmlFor='first-check-box'>
            <input type="checkbox"
                checked={firstCheckbox.firstCheckBox}
                onChange={() => setFirstCheckbox(
                    {firstCheckBox: !firstCheckbox.firstCheckBox}
                )}>
            </input>
            First Check Box
        </label>
        <label htmlFor='second-check-box'>
            <input
                type="checkbox"
                checked={secondCheckbox.secondCheckBox}
                onChange={() => setSecondCheckbox(
                    {secondCheckBox: !secondCheckbox.secondCheckBox}
                )}>
            </input>
            Second Check Box
        </label>
    </div>
  );
}

export default App;

上面,为了清楚起见,我使用了输入元素的 onChange() 事件。 这需要用户点击实际的复选框。 我更愿意让他们点击 label 或复选框上的任意位置。 为此,我们可以使用 label 元素的 onClick 事件:

为了防止在控制台中抱怨输入不是 controller,我也将它们标记为只读。

应用程序.js:

import React, { useState } from 'react';

function App() {
  var [ firstCheckbox, setFirstCheckbox ]   = useState({firstCheckBox: true});
  var [ secondCheckbox, setSecondCheckbox ] = useState({secondCheckBox: false});
  return (
    <div style={{display:'flex', flexDirection: 'column'}}>
        <label
            htmlFor='first-check-box'
            onClick={() => setFirstCheckbox({firstCheckBox: !firstCheckbox.firstCheckBox})}>
            <input type="checkbox" checked={firstCheckbox.firstCheckBox} readOnly/>
            First Check Box
        </label>
        <label
            htmlFor='second-check-box'
            onClick={() => setSecondCheckbox({secondCheckBox: !secondCheckbox.secondCheckBox})}>
            <input type="checkbox" checked={secondCheckbox.secondCheckBox} readOnly/>
            Second Check Box
        </label>
    </div>
  );
}

export default App;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM