inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

[input 속성 및 state 관리] 사용자 입력 처리하기

해결된 질문

603

moon

작성한 질문수 4

0

안녕하세요.

사용자 입력 처리하기 강의 관련 질문입니다.

 

input 태그를 통해 사용자 입력을 받고, 상태 관리하면, 상태에 사용자의 입력이 반영되는 게 한 단계씩 늦는 것 같습니다. (그 이유가 useState가 비동기적으로 처리된다고 들은적이 있는 것 같은데, 정확히 이해가 가지 않아서 질문드립니다.)

 

아래 코드의 handleOnChange함수에서,

Q1) e.target.name, e.target.value은 제깍제깍 실시간으로 반영이 되는데, input state는 한 단계 늦게 반영이 됩니다. 이런 현상이 발생하는 이유는 무엇이고, 이건 개발하는데 문제가 되지 않는 이유는 뭔지? 가 궁금합니다!

 

import { useState } from 'react';

const DiaryEditor = () => {
  const [input, setInput] = useState({
    author: '',
    content: '',
    emotion: 1,
  });

  const handleOnChange = (e) => {
    console.log(e.target.name);
    console.log(e.target.value);
    setInput({ ...input, [e.target.name]: e.target.value });
    console.log(input);
  };

  const handleSubmit = () => {
    console.log(input);
    alert('오늘의 일기가 저장되었습니다!');
  };

  return (
    <div className='DiaryEditor'>
      <h2>오늘의 일기</h2>
      <div>
        <input name='author' value={input.author} onChange={handleOnChange} />
        <p>{input.author}</p>
      </div>
      <div>
        <textarea
          value={input.content}
          name='content'
          onChange={handleOnChange}
        />
        <p>{input.content}</p>
      </div>
      <div>
        <span>감정 지수 : </span>
        <select
          onChange={handleOnChange}
          name='emotion'
          value={input.emotion} 
        >
          <option value={1}>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
          <option value={5}>5</option>
        </select>
      </div>
      <div>
        <button onClick={handleSubmit}>저장하기</button>
      </div>
    </div>
  );
};

export default DiaryEditor;


Q2) 위처럼 input이란 state는 한단계씩 늦게 반영이 되는데, select태그의 value 속성을 주는 목적은 무엇인가요??
인풋의 value 속성은 실시간으로 인풋의 값과 상태를 동기화해주는 목적으로 사용한다고 생각했는데,

state가 곧바로 변하지 않는거면, 이 인풋의 value 속성은 무용지물인 것 아닌가라는 생각이 들어 질문드립니다.

 

        <select
          onChange={handleOnChange}
          name='emotion'
          value={input.emotion} 
        >


Q3) useState의 초기값은 반드시 빈문자열등으로 인자를 전달하는 게 나은가요? 아무 인자도 전달하지 않으면 어떤 잠재적인 에러 발생 가능성이 있는건가요?

javascript react

답변 1

0

이정환 Winterlood

안녕하세요 이정환입니다.

우선 useState의 setState가 비동기적으로 동작하는 이유는 컴포넌트가 렌더링 하는 UI를 변경을 반영한 상태로 다시 렌더링해야 하기 때문입니다.

더 구체적으로 말씀드리자면 setState가 호출되었을 때 리액트가 내부적으로 컴포넌트를 다시 호출하여 변경된 State 값이 적용된 UI를 렌더링 하도록 해 화면을 업데이트 하기 위함입니다.

따라서 다음과 같은 함수가 호출되면 React는 함수를 끝 마친 이후에 해당 컴포넌트를 다시 호출해 리렌더를 발생 시키기 때문에 console.log(input) 까지는 변경된 State의 값이 즉시 반영되지 않는 것 입니다.

  const handleOnChange = (e) => {
    console.log(e.target.name);
    console.log(e.target.value);
    setInput({ ...input, [e.target.name]: e.target.value });
    console.log(input);
  };

중요한 것은 컴포넌트 역할을 하는 함수 자체가 다시 호출되어야 하기 때문에 이렇게 동작한다고 이해하시면 될 것 같습니다!

<select> 태그의 value 속성을 주는 이유는 앞서 말씀 드린 대로 State가 변경되어 컴포넌트 역할을 하는 함수가 다시 호출되었을 때 변경된 State를 반영한 UI를 렌더링 시키기 위함 입니다.

구체적으로 순서를 나열해보자면 이렇습니다.

  1. 초기 상태 렌더링

  2. setState 호출로 인해 상태 업데이트

  3. React가 내부적으로 상태가 변경된 컴포넌트 재 호출

  4. 재 호출된 컴포넌트는 변경된 State를 반영한 UI를 다시 리턴

 추가로 useState의 초기값으로 ""을 넣어주는 이유는 다음과 같은 경우 오류가 발생할 수 있기 때문에 그렇습니다.

const App() => {
    const [text, setText] = useState(); // text 초기값은 undefined
    return (
        <div>
            {text.toUpperCase()}
            // undefined is not object 에러 발생
        </div>
    );
}

자바스크립트에서는 undefined 값을 객체로 착각하고 메서드를 호출하려고 하거나 프로퍼티에 접근하려고 하면 런타임 오류를 발생시킵니다. 따라서 문자열로 예상될 State의 값을 초기화 할 때에는 undefined으로 초기화 시키는 것 보다 ""을 통해 빈 문자열로 초기화 시켜두는 것이 훨씬 안전합니다.

useEffect와 lifecycle문의

0

36

2

프론트엔드 학습 수준 문의

0

48

2

리액트 챕터별 코드에서 eslint 설정파일이 없어요

0

53

2

데이터 로딩중 화면만 계속 나와요!!

0

57

2

퍼블리셔일경우 어느정도 수준까지 강의를 들어야할까요

0

84

2

이후의 커리큘럼 문의

0

104

2

실슬환경 설정에서 save후 console.log 부분이 새로고침이 안되는현상입니다.

0

53

2

최적화 관련 질문있습니다 (useMemo 등)

0

86

3

프로바이더 컴포넌트의 위치는 어떤 기준인가요?

1

82

3

Date 객체에 관련하여 질문드립니다.

0

87

2

리액트 개정판 교재 질문

0

60

2

예제코드가 안나와요!

0

78

2

select a variant 선택에서 javascript와 javascript+react compiler 중 무엇을 선택해야하나요? com

0

110

2

onMouseEnter 관련 문의 드립니다

0

93

3

배열의 렌더링 관련 질문 드립니다.

0

73

2

2:40초 refObj를 콘솔로 출력시 오류가 발생합니다.

0

114

2

TS, 리액트 강의중에 뭘 먼저 수강하는게 좋을까요?

0

138

2

useCallback 적용한 onCreate, onUpdate, onDelete 함수..

0

71

1

vs code 자동완성관련 문의

0

119

2

91강 useEffect내에서 상태변화함수 호출시 발생하는 에러

1

185

2

87강 필터 함수 질문

0

71

2

useRef, useState count 비교

0

67

2

안된다고했던 이유가 무엇이었는지 모르겠습니다

0

92

2

85강에서 객체를 왜 클래스로 만들어서 new 하지 않는건지 궁금합니다.

0

77

2