首页 > 解决方案 > React 中的受控复选框

问题描述

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

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>
      ))}

标签: reactjsuse-state

解决方案


问题

您正在比较it.id !== it.id哪个总是评估为假。

解决方案

state.address是 id 的数组,而不是具有id属性的对象,您希望将每个对象与事件对象中的输入进行name比较onChange

  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. 使用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>
  )
}

编辑受控复选框反应(分叉)


推荐阅读