反应材料 ui 全选复选框

时间:2021-07-05 05:09:43

标签: javascript reactjs

我需要在选择复选框全选时,选中列表中的其余复选框,并且可以单独选择每个复选框。 But when select one of the checkboxes does not checked the previous checkbox.

sandbox

const options = [ 'Selected Item 1', 'Selected Item 2', 'Selected Item 3'];

export default function App() {

  const [selected, setSelected] = useState([]);
  const isAllSelected = 
      options.length > 0 && selected.length === options.length;

  const handleChange = (event) => {
    const value = event.target.value;
    console.log(value)
    if (value === "all") {
      setSelected(selected.length === options.length ? [] : options);
      return;
    }
    setSelected(value);
  };  

  const listItem = options.map((option) => {        
    return (
        <div key={option}>
          <Checkbox 
            value={option}
            onChange={handleChange} 
            checked={selected.includes(option) } />
          <span>{option}</span>
        </div>
    )
  })

  return (
    <div style={{ display: 'flex', alignItems: 'center', margin: 10 }}>
        <Checkbox 
          value='all' 
          onChange={handleChange} 
          checked={isAllSelected} 
          />
        <span> Select All</span>
        {listItem}
    </div>
  );
}

3 个答案:

答案 0 :(得分:0)

需要更新 selected 选项数组,而不是直接在 handleChange 方法中赋值。所以首先检查是否选择列表 contains the checked option 如果它包含然后 remove 它,否则 add 它到所选列表。

 const handleChange = (event) => {
    const value = event.target.value;
    console.log(value);
    if (value === "all") {
      setSelected(selected.length === options.length ? [] : options);
      return;
    }
    // added below code to update selected options
    const list = [...selected];
    const index = list.indexOf(value);
    index === -1 ? list.push(value) : list.splice(index, 1);
    setSelected(list);
};

Sandbox link here

答案 1 :(得分:0)

当您单击“全部”复选框以外的复选框时,您只是将 selected 状态设置为该值:setSelected(value);。此代码有 2 个问题 - 1) 在您的情况下,selected 状态应始终为数组,但您将其更改为字符串。 2) 您忽略了可能添加到 selected 状态的任何先前值。您必须确定点击的复选框是否已经处于 selected 状态。如果没有,您应该将其添加到状态中。如果是,那么您应该将其从状态中删除。您可以这样做:

const handleChange = (event) => {
    const value = event.target.value;
    console.log(value)
    if (value === 'all') {
      setSelected(selected.length === options.length ? [] : options);
      return;
    }
    if (selected.indexOf(value) !== -1) { // if value already present
      const newSelected = selected.filter((s) => s !== value );
      setSelected(newSelected);
    } else { // if value not present
      setSelected([ ...selected, value ]);
    }
}

答案 2 :(得分:0)

你可以创建一个像 [{data:any, selected: boolean}, {data:any, selected: boolean}] 这样的数据结构 然后循环遍历它并将它们显示为

  const [items, setItems] = useState<Asset[]>([]);

  const [select, setSelect] = useState(false)

  const handleChange = (index, checked) => {
   
     if(select && !checked) setSelect(false)

     const itemRef = [...items];

     itemRef[index].selected = checked

     setItems([...itemRef]);
  } 

  const handleChangeAll = (checked) => {
     const itemRef = [...items];
    
     itemRef.forEach((_item, i) => {
        itemRef[i].selected = checked

     })

     setSelect(checked)
 
     setItems([...itemRef]);
  } 

   
  ------
   All selection checkbox
 
   <Checkbox
       checked={select}
       onChange={(_e, checked) => handleChangeAll(checked)} 
      />

  ** items **
  
  items.map((item, i) => (
     <Checkbox
       key={item.data.id} 
       checked={item.selected}
       onChange={(_e, checked) => handleChange(index, checked)}  
      />

  ))


一旦完成,如果您想提取选定的数据,您只需应用基于 item.selected 数组中的 items 的过滤方法,