본문 바로가기

FrontEnd/React

클래스 컴포넌트의 state속성에 대하여, ref 속성에 대하여

클래스 컴포넌트 안의 state역시 속성(property)이다. 그리고 클래스 컴포넌트의 속성은 변수와 같은 개념이라고 우선은 알아두자.

리엑트에서 데이터는 
1. 변수에 넣거나
2. state에 넣는다. 

리엑트를 웹앱처럼 동작하게 만들고 싶다면 중요한데이터는 state를 사용한다. state로 등록된 데이터가 바뀌면 그것은 곧 새로고침 없이도 리랜더링된다. 변수와 state로 관리되지 않는 것은 변경되어도 자동 re-rendering이 되지 않음. 

state에 마우스를 올려보면 아래와 같이 state역시 속성(property)임을 알수 있다.
state밖에 선언했지만 timeout, startTime또한 속성이다.

======================================================================================

useState만 사용하면 해당 인수가 prop이 변경될 때마다가 아니라 처음에만 사용되기 때문에 작동하지 않는다. 이 문제를 해결하려면 들어오는 객체를 state로 사용할 때는 새 객체를 만들어야 한다.

그렇지 않으면 리액트는 객체의 변경을 감지하지 못한다.(객체는 참조형 data이기 때문에 객체 내부 값이 변해도 객체 자체의 주소값이 변하기 않기 때문)

const Message = ()=>{
    const [messageObj,setMessageObj] = useState({message:''})

    return (
        <>
           <input type='text'
                  value={messageObj.message}
                  onChange={e=>{
                  // 동작하지 않는 예시
                     messageObj.message = {e.target.value};
                     setMessage(messageObj) 

                 // 동작하려면 새로운 객체를 만들어야 한다.
                      const new = {message:e.target.value};
                      setMessage(newMessageObj)

                 // 아래와 같은 방법도 가능하다
                       setMessage(prevState=>{
                           return {...prevState,message:e.target.value}
                       })

                }} />
        </>
    )
}

=======================================================================================

state의 특징

 

  • state가 변경되면 React는 이를 감지해 render가 일어난다.
  • state는 바로 할당하는 방식으로 변경하면 react가 변화를 감지하지 못하므로 setState를 이용해 변경한다.
  • setState는 비동기로 처리되므로, setState 바로 다음 명령에서 새로운 값이 반영되지 않을 수 있음
  • setState는 첫 번째 인자로 이전 상태의 값을 갖도록 해줄수 있다. 반면 그렇게 하지 않을 수도 있음.

=======================================================================================

Ref속성은 언제 사용하나? DOM을 꼭 직접적으로 건드려야 할때. 그렇다면 언제 DOM을 직접적으로 건드려야만 하나? 특정 input에 포커스를 주는 경우,  스크롤 박스를 조작하는 경우, Canvas요소에 그림을 그리는 경우. ref를 사용하는 방법은 크게 두가지로 아래와 같다. 
ref를 사용하는 방법: https://yjym33.tistory.com/36