[React] useState 사용법 - 3

JCH27·2023년 11월 22일
0

react

목록 보기
3/8
post-custom-banner

useState 사용법 3번째 글이다.
이번엔 form 태그와 input 태그로 참조형 스테이트를 제어하는 방법을 정리해보고자 한다.
간단한 메모 기능을 구현하며 정리해보겠다.


알아야 할 Javascript 문법

  • useState() 기본 사용법
  • 구조 분해 할당, 스프레드 연산자

state 설계

  • state 자료 구조

  1. memos = [ { id, memo, isChecked }, { id, memo, isChecked }, ... ];
     배열[ 객체1, 객체2, ... ] => 주요 메모 데이터

 
2. todo = '문자열' => memos에 추가될 객체의 memo 프로퍼티에 할당 될 데이터

  • setState 호출 정리

  1. setMemos : form 태그의 onSubmit 그리고 button 태그의 onClick 이벤트로 'setMemos' 함수 호출

 
2. setTodo : input 태그의 onChange 이벤트로 'setTodo' 함수 호출


메모 기능 구현하기

  1. state 선언

	// 초기 데이터를 변수로 선언
	const initialMemos = [
      {
        id : 0,
        memo : '돈벌기',
        isChecked : false
      },
      {
        id : 1,
        memo : '주식 투자하기',
        isChecked : false
      },
      ...
    ];
    // 'memos' state 할당.
	const [memos, setMemos] = useState( initialMemos );
	
	// 'todo' state 할당
	const [todo ,setTodo] = useState('');

 

  2. 요소 구현

	return (
    <div style={style.div}>
      // 체크되지 않은 메모 리스트 제목
      <h1>해야할 일</h1>
      <ol>
        // 'memos' state를 map 함수로 접근해 요소 랜더링
        {memos.map((item)=> {
          if(!item.isChecked){
          // isChecked의 값이 false(체크되지 않은)인 객체인 경우
          // li 요소를 리턴
            return (<li key={item.id}>
              		  // input=[checkbox]의 onChange => handleCheck 함수에 event 와 데이터 id 값 전달하여 호출
                      <input id={`chk${item.id}`} type="checkbox" value={true} onChange={(e)=>handleCheck(e, item.id)} />
                      <label htmlFor={`chk${item.id}`}>{item.memo}</label>
                    </li>);
          }else{
          // isChecked의 값이 true(체크된)인 객체인 경우 display : none 속성을 부여한다.
          // 빈 값을 리턴하는 경우 li 요소 리턴이 아니기 때문에 경고 출력
		  // 따라서 filter로 제한사항을 두거나 한 줄 삼항 연산자 사용 권장됨
            return (<li key={item.id} style={style.none}></li>);
          }
        })}
      </ol>
      
	  // input=[text] 태그의 onSubmit => handleSubmit 함수 호출
      <form onSubmit={handleSubmit}>
		// onChange => handleChangeTodo 함수 호출
		// input 요소의 value 속성을 'todo'(제어할 스테이트)로 할당해주어야 값 변경 가능!
        <input type="text" value={todo} onChange={handleChangeTodo} placeholder='추가할 메모를 적어주세요' />
        <button type="submit"> 메모 추가하기 </button>

      </form>
	  
	  // 체크된 메모 리스트 제목
      <h2>완료한 일</h2>
      <ul>
		// isChecked의 값이 true(체크된)인 객체인 경우
		// li 요소를 리턴
        {memos.map((item) => (item.isChecked&&<li key={item.id}> {item.memo} </li>))}
      </ul>

    </div>
  );

 

  3. 이벤트 핸들러 함수 구현

	// 1. input=[text] 태그의 onChange 이벤트로 호출되는 함수로 'todo'를 제어
	const handleChangeTodo = (e) => {
    	// setTodo 호출하여 'todo' 변경!
      	// input 태그에 값을 입력하면
    	// 이벤트 target(input)의 value값을 'todo'에 할당
    	setTodo(e.target.value);
  	}

  	// form 태그의 onSubmit 이벤트로 호출되는 함수로 'memos' 와 'todo'를 제어
  	const handleSubmit = (e) => {
    	// preventDefault() 메서드로 form 태그의 submit 이벤트를 막는다.
    	e.preventDefault();
      
    	// 'memos'에 추가할 id 값과 객체를 구현한다. memo 프로퍼티의 value는 'todo'(state)값으로 할당한다.
      	// 추가될 객체의 id 값은 memos의 길이로 할당한다.
    	const id = parseInt(memos.length);
    	const obj = {
      		id,
          	// memo 프로퍼티의 값은 'todo'(입력된 state) 값으로 할당
      		memo : todo,
      		isChecked : false
    	}
		
        // setMemos 호출하여 'memos' 변경!
		// 이전 state(memos) 값에 객체를 추가해준 배열을 리턴
    	setMemos((prev) => ( [ ...prev, {...obj} ] );

        // setTodo 호출하여 'todo' 변경!
    	// 'todo'(input태그의 value 속성값)를 빈 문자열로 할당한다.
    	setTodo('');
  	}

    // input=[checkbox] 태그의 onChange 이벤트로 호출되는 함수로 'memos'를 제어
 	const handleCheck = (e, id) => {
      	// setMemos 호출하여 'memos' 변경!
    	setMemos((prev) => {
          	// 이전 스테이트 값을 복사하여 변수로 할당
      		const result = [...prev];
          	// 일부(isChecked)값만 변화시킨다.
      		result[id]["isChecked"] = e.target.value;
          	// 수정 완료된 배열을 리턴해 'memos'스테이트에 할당
      		return [ ...result ];
    	});
  	}

  4. 결과


마치며

함수형 컴포넌트에서 state를 구현하는 방법을 정리해봤다.
더 자세한 state 사용 규칙도 정리할 필요가 있겠다.

다음 글은 useEffect를 정리해 보도록 하겠다.

profile
포기하지 않는 키보드 워리어
post-custom-banner

0개의 댓글