javascript - 处理多个复选框的填充状态

标签 javascript reactjs jsx

我有一个表单,可以根据一些数据构建复选框列表:

<fieldset className="visibility">
        <div className="input-container checkbox">
          <span className="label">Visible to</span>
          <ul>
            {
              allForces.map(force => {
                if (force.name !== 'White' && force.name !== currentMarkerForce) {
                  return (
                    <li key={force.uniqid}>
                      <label>
                        <input onChange={handleVisibilityChange} name={`visibility-${_.kebabCase(force.name)}`} type="checkbox" value={force.name} checked={markerVisibleTo.includes(force.name) }/>
                        {force.name} cell
                      </label>
                    </li>
                  )
                }
              })
            }
          </ul>
        </div>
      </fieldset>

由于通常至少会出现并可以检查 2 个项目,因此我为其编写了一个处理程序,该处理程序在回发到状态之前填充一个数组,该数组的内容最初是从现有状态填充的:

 const visibilityChecked = [...markerVisibleTo]

  const handleVisibilityChange = ({ target }) => {
    const { checked, value } = target
    checked ? visibilityChecked.push(value) : visibilityChecked.pop(value)
    setMarkerVisibleTo(visibilityChecked)
}

最后一行是对 useState 钩子(Hook)的调用,大多数情况下都有效,但有时我会得到一个奇怪的行为,即选择了错误的复选框:

An example of the bug

任何人都可以帮助阐明导致此问题的原因吗?

最佳答案

我可能猜测会发生这种情况,因为状态更新是异步的,当您尝试使用 setMarkerVisibleTo() 应用更改时,您的状态与您假设的状态不同,您可以尝试将const VisibilityChecked = [...markerVisibleTo] 进入 handleVisibilityChange() 正文:

const handleVisibilityChange = ({ target }) => {
    const visibilityChecked = [...markerVisibleTo]
    const { checked, value } = target
    checked ? visibilityChecked.push(value) : visibilityChecked.pop(value)
    setMarkerVisibleTo(visibilityChecked)
}

或者,正如我所写:

const handleVisibilityChange = ({target:{checked,value}}) => {
    const visibilityChecked = checked ? 
        [...markerVisibleTo, value] : 
        [...markerVisibleTo].filter(val => val != value)
    setMarkerVisibleTo(visibilityChecked)
}

您可以在这里找到完整的演示:

//dependencies
const { render } = ReactDOM,
      { useState } = React

//mocking source data      
const checkItems = [...'abcd']      

//check list component
const CheckList = ({items}) => {
  const [visibleMarkers, setVisibleMarkers] = useState(checkItems),
        onVisibilityChange = ({target:{checked,value}}) => {
            const visibilityChecked = checked ? 
                [...visibleMarkers, value] : 
                [...visibleMarkers].filter(val => val != value)
            setVisibleMarkers(visibilityChecked)
        }
  return (
  <div>
      <ul>
        {
          items.map((item,key) => (
            <li {...{key}}>
              <label>
                Option {item}
                <input 
                  type="checkbox" 
                  value={item} 
                  checked={visibleMarkers.includes(item)}
                  onChange={onVisibilityChange}
                />
              </label>
            </li>
          ))
        }
      </ul>
      <span>visibleMarkers: {JSON.stringify(visibleMarkers)}</span>
  </div>
  )
}

//render
render (
  <CheckList items={checkItems} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

关于javascript - 处理多个复选框的填充状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59991150/

相关文章:

javascript - 使用React.js向多个用户发送电子邮件而没有任何后端(node.js或express)

javascript - 在单独的组件中获取 json

javascript - react 路由器路由中的尾部正斜杠

javascript - React JSX 中的动态标签名称

javascript - 为什么 js 服务器收不到 HTTP post 请求?

javascript - 如何在javascript中子串

javascript - 如何让鼠标悬停不覆盖鼠标单击?

javascript - d3.nest 具有多列

javascript - this.setState 在 componentDidUpdate 中不起作用

javascript - shouldComponentUpdate() 没有被调用