美文网首页
useSelections

useSelections

作者: skoll | 来源:发表于2020-09-07 20:55 被阅读0次

常见联动 checkbox 逻辑封装,支持多选,单选,全选逻辑,还提供了是否选择,是否全选,是否半选的状态

import {useState,useMemo} from 'react'

export default function useSelections<T>(items:T[],defaultSelected:T[]=[]){
    const [selected,setSelected]=useState<T[]>(defaultSelected)
    // 这里应该判断下默认的值是否在items里面


    // 这里像是一个更小的hook
    const {selectedSet,isSelected,select,unSelect,toggle}=useMemo(()=>{
        const selectedSet=new Set<T>(selected)
        // 用一个set结构装所有被选择的元素
        // 我以为他会返回一个数据结构,来表示当前的选择状态,但实际上他返回的是方法,每一个单独的元素拿这个方法来判断是否被选中

        const isSelected=(item:T)=>selectedSet.has(item)

        const select=(item:T)=>{
            selectedSet.add(item)
            return setSelected(Array.from(selectedSet))
            // 里面的结果同步到外面
        }

        const unSelect=(item:T)=>{
            selectedSet.delete(item)
            return setSelected(Array.from(selectedSet))
        }
        const toggle=(item:T)=>{
            if(isSelected(item)){
                unSelect(item)
            }else{
                select(item)
            }
        }
        // 复杂的方法已经可以使用内部之前定义的方法了

        return {
            selectedSet,isSelected,select,unSelect,toggle
        }
    },[selected])
    // 所有被选择的元素都在这个容器里面

    // 操作其余多个数据的集合方法
    const {
        selectAll,
        unSelectAll,
        noneSelected,
        allSelected,
        partiallySelected,
        toggleAll,
    }=useMemo(()=>{

        const selectAll=()=>{
            items.forEach((o)=>{
                select(o)
            })

            setSelected(Array.from(selectedSet))
        }

        const unSelectAll=()=>{
            items.forEach((e)=>{
                selectedSet.delete(e)
            })
            setSelected(Array.from(selectedSet))
        }

        const noneSelected=selectedSet.size===0?true:false

        const allSelected=selectedSet.size===items.length?true:false

        const partiallySelected= !noneSelected && !allSelected

        const toggleAll=()=>(allSelected?unSelectAll():selectAll())

        return {
            selectAll,
            unSelectAll,
            noneSelected,
            allSelected,
            partiallySelected,
            toggleAll,
        }
    },[selectedSet,items])

    return {
        selected,
        isSelected,
        select,
        unSelect,
        toggle,
        selectAll,
        unSelectAll,
        toggleAll,
        allSelected,
        noneSelected,
        partiallySelected,
        setSelected,
    } as const
}

import useSelections from '../useSelections'


export default function(){
  const [hideOdd,setHideOdd]=useState(false)

  const list=useMemo(()=>{
    if(hideOdd){
      return [2,4,6,8]
    }return [1,2,3,4,5,6,7,8]
  },[hideOdd])
  
  const {
    selected,
    allSelected,
    isSelected,
    toggle,
    toggleAll,
    partiallySelected,
  }=useSelections(list,[1])
  
  console.log(selected)
  console.log(allSelected)
  return (
    <div>
      {JSON.stringify(selected)}
      <hr/>
        {
          list.map((o)=>(
            <div key={o}>
              <input type="checkbox" checked={isSelected(o)} onClick={()=>toggle(o)} />
              {o}

            </div>
          ))
        }
        <hr/>
        <button onClick={toggleAll}>全选</button>
    </div>
  )
}

相关文章

  • useSelections

    常见联动 checkbox 逻辑封装,支持多选,单选,全选逻辑,还提供了是否选择,是否全选,是否半选的状态

网友评论

      本文标题:useSelections

      本文链接:https://www.haomeiwen.com/subject/lnwlektx.html