본문 바로가기
JavaScript/React

[React] 리액트 Checkbox 상태관리

by 봉이로그 2023. 1. 3.

리액트에서 체크박스 기능을 구현하는 방법은 여러가지가 있습니다.

 

1. 라이브러리를 사용하는 방법

ex) form, state 라이브러리

 

https://react-hook-form.com/get-started/

 

Get Started

Performant, flexible and extensible forms with easy-to-use validation.

react-hook-form.com

 

 

2. state를 사용하는 방법

 

이번글에서는 state를 사용하여 구현하는 방법을 소개합니다.

 

 

Array vs Set

state를 사용할 경우, 일반적으로 배열을 사용하지만, Set을 사용할 경우 코드작성에 있어서 조금 더 이점을 가질수 있습니다.

 

실무적관점에서 이점으로 2가지 정도 있을것 같습니다.

 

1. 중복 방지 - Set은 중복을 허용하지 않는 자료구조

2. 특정요소를 제거할 수 있는 메소드를 제공

 

 

Example

checkbox를 이용하여 직원을 추가하고 삭제하는 코드를 작성해 보겠습니다.

 

여기 직원리스트 (employees) 데이터가 있습니다.

const employees = [
	{id: 1, name: '임직원'},
	{id: 2, name: '홍길동'},
	{id: 3, name: '이순신'}
]

 

직원들의 고유한 Id를 저장하는 state를 생성 합니다.

const [employeeIds, setEmployeeIds] = useState(new Set());

 

체크박스를 생성합니다.

 

const Example = ()=> {    
    return (
    	...
    	// 전체 선택,해제
		<input type="checkbox" checked={employees.length === employeeIds.size}
		     onChange={handleSelectAll} />
        
        // 개별 선택,해제
        employees.map((employee)=> {
        	<input type="checkbox" key={employee.id} 
            	checked={employeeIds.has(employee.id)}
                onChange={()=> handleSelect(employee.id)} />
        })
        ...
    );
}

export default Example;

관려된 함수를 추가합니다.

// 전체 선택,해제
    const handleAllSelect = () => {
      const updatedCheckedIds = new Set(employeeIds);
      if (updatedCheckedIds.size === employees.length) { 
      // 직원id목록 사이즈와 직원목록 갯수가 동일한 경우
      
        updatedCheckedIds.clear(); // 전체 초기화
      } else {
        employees.forEach((employee) => {
          updatedCheckedIds.add(employee.id); // 직원리스트에 있는 id들을 직원id목록에 추가합니다.
        });
      }
      setEmployeeIds(updatedCheckedIds); // 직원id목록 state를 업데이트합니다.
	};
    
//개별 선택,해제
  const handleSelect = (id: number) => { // id를 인자로 넘깁니다.
      const updatedEmployeeIds = new Set(employeeIds); // 중복을 제거합니다.
      if (updatedEmployeeIds.has(id)) updatedEmployeeIds.delete(id);
      // 인자로 넘긴 id가 존재할 경우 제거합니다.
      
      else updatedEmployeeIds.add(id);
      // 인자로 넘긴 id를 추가합니다.
      
      setEmployeeIds(updatedEmployeeIds);
      // 직원id목록 state를 업데이트합니다.
  };

전체코드

const employees = [
	{id: 1, name: '임직원'},
	{id: 2, name: '홍길동'},
	{id: 3, name: '이순신'}
]

const Example = ()=> {    

const [employeeIds, setEmployeeIds] = useState(new Set());

const handleAllSelect = () => {
      const updatedCheckedIds = new Set(employeeIds);
      if (updatedCheckedIds.size === employees.length) {       
        updatedCheckedIds.clear();
      } else {
        employees.forEach((employee) => {
          updatedCheckedIds.add(employee.id);
        });
      }
      setEmployeeIds(updatedCheckedIds);
	};
    
const handleSelect = (id: number) => {
      const updatedEmployeeIds = new Set(employeeIds);
      if (updatedEmployeeIds.has(id)) updatedEmployeeIds.delete(id);
      else updatedEmployeeIds.add(id);
      setEmployeeIds(updatedEmployeeIds);
  };

    return (
    	...
		<input type="checkbox" checked={employees.length === employeeIds.size}
		     onChange={handleSelectAll} />
        
        employees.map((employee)=> {
        	<input type="checkbox" key={employee.id} 
            	checked={employeeIds.has(employee.id)}
                onChange={()=> handleSelect(employee.id)} />
        })
        ...
    );
}

export default Example;

결과물