React 中的受控复选框

Controlled checkbox in React

我正在尝试将所有选中的复选框放入状态数组中。我可以将值添加到数组,但是当我取消选中该框时我无法删除该值。我尝试过使用拼接和按索引删除,也尝试过通过过滤器删除。它可以工作,但工作缓慢且不正确。例如,我可以取消选中所有复选框,并且一个值保留在状态中。请检查我做错了什么 这是一个沙盒 link 和下面的代码

const [state, setState] = useState({
    address: [],
  })

  const checkboxChange = (e) => {
    const { name, checked } = e.target
    if (checked === true) {
      setState((prevState) => ({
        ...prevState,
        address: [...prevState.address, name],
      }))
    }
    if (checked === false) {
      setState((prevState) => ({
        ...prevState,
        address: [...prevState.address].filter((it) => it.id !== it.id),
      }))
    }
  }
{list.map((it, index) => (
        <div key={it.id}>
          <label>
            <input
              className="mr-2"
              checked={state.address.index}
              key={it.id}
              name={it.id}
              defaultValue="false"
              onChange={checkboxChange}
              type="checkbox"
            />
            {it.name}
          </label>
        </div>
      ))}

问题

您正在比较 it.id !== it.id,它将总是 评估为 false。

解决方案

state.address 是一个 id 数组,而不是具有 id 属性 的对象,并且您想将每个对象与 name 中的输入进行比较=16=]事件对象。

  1. 只过滤prevState.address
  2. 比较el !== name

代码

const checkboxChange = (e) => {
  const { name, checked } = e.target;

  if (checked) {
    setState((prevState) => ({
      ...prevState,
      address: [...prevState.address, name],
    }))
  } else {
    setState((prevState) => ({
      ...prevState,
      address: prevState.address.filter((el) => el !== name),
    }))
  }
}

受控输入

如果你真的想控制你的输入,那么我建议:

  1. 将选中的值存储在映射中
  2. 只需切换 onChange 事件
  3. 中选中的值
  4. 使用 value 属性与输入的 defaultValue 属性

代码

const App = (props) => {
  const [state, setState] = useState({
    address: {}, // <-- object map
  })

  useEffect(() => {
    console.log(state)
  }, [state])

  const checkboxChange = (e) => {
    const { name } = e.target
    setState((prevState) => ({
      ...prevState,
      address: {
        ...prevState.address,
        [name]: !prevState.address[name], // <-- toggle state
      },
    }))
  }

  return (
    <div>
      {list.map((it, index) => (
        <div key={it.id}>
          <label>
            <input
              className="mr-2"
              checked={state.address.index}
              key={it.id}
              name={it.id}
              value={state.address[it.id]} // <-- set from checked state
              onChange={checkboxChange}
              type="checkbox"
            />
            {it.name}
          </label>
        </div>
      ))}
    </div>
  )
}