[React] 함수형 컴포넌트에서 상태 올리기

React를 통해 본격적으로 프로젝트를 하고 있습니다.

리엑트는 클래스의 종류는 크게 클래스 컴포넌트와 함수형 컴포넌트로 구분할 수 있는데 React.js 공식 사이트 에서는 Tutorial 이 주로 클래스 컴포넌트 형태로 소개되어 있는데에 비해 요즘 제가 하고 있는 Next.js에서는 Tutorial 전체가 함수형으로 구성되어있습니다.

이미 구성된 프로젝트가 아닌 새로운 프로젝트에서는 함수형 컴포넌트를 사용하려고 하는 모습들이 보이는 것 같습니다. 훨씬 간결해보이기도 하구요.

함수형 컴포넌트에서의 State Management

함수형 컴포넌트에서는 setState를 사용하지 않고, useState를 사용하면 됩니다. 정말 간단하죠.

import { useState } from 'react'

useState로 state 값 읽기

일단 useState는 아래처럼 사용하면 됩니다.

const [ stateValues, setStateValues ] = useState({
 id: 1,
 content: 'hello'
});

우선 stateValues, setStateValues 라는 상수로 지정해두었습니다.

첫번째 stateValues는 useState 를 통해 저장되는 값을 사용하는 용도로 쓰는 상수입니다.

id를 호출하고 싶다면 간단하게 stateValues.id 로 호출할 수 있습니다.

useState로 state 값 쓰기

useState를 통해 state에 값을 수정하는 것은 불가능합니다. 그렇지만 우리는 값을 수정하지 않고 덮어씌울 수는 있습니다.

아래처럼 사용하면 쉽게 useState를 쓰게됩니다. 여기서는 content를 hello에서 hi로 바꿔보겠습니다.

setStateValue({
 ...stateValues, // 이런 형태를 Spread Operator 라고 합니다.
 content: 'hi'
})

이렇게 하면 stateValues의 기존 값은 유지하고, value의 값만 hi로 만들 수 있습니다.

함수형 컴포넌트에서 state 내리고 올리기

제가 블로그에 노트하는 것은 이것 때문입니다. 프로젝트를 시작하면서 React를 겁냈던 이유이기도 했습니다.

그래서.. 지금부터 컴포넌트를 올리고 내리는 방법에 대해 본격적으로 소개하려고 합니다.

부모 Component 에서 자식 Component 에게 State 를 내리기

함수형 컴포넌트에서 부모 Component 에서 자식 Component 에게 State를 내리는 방법은 간단합니다.

부모 컴포넌트부터 한번 살펴보겠습니다.

// ParentComponent.js
export default ParentComponent = () => {
 const [ stateValues, setStateValues ] = useState({
   id: 1,
   content: 'hello'
})
 
 return (
<ChildComponent id={stateValues.id} content={stateValues.content} />
)
 
}

이렇게 하면 ChildComponent 에 stateValues 의 내용이 전달되겠죠. 여기까지는 쉽습니다.

조금 더 살펴보겠습니다.

// ChildComponent.js

export default ChildComponent = props = { // props를 파라미터로 받게 하고..
 return (
<div>
  <p>{props.id}</p> // 이렇게 사용할 수 있습니다.
<p>{props.content}</p> // 이렇게 하면 id, content가 나타나겠죠.
   </div>
)
}

여기까지는 꽤 괜찮습니다. 저는 Child Component에서 Comment 를 추가로 작성해보려고 합니다.

그리고 Child Component 에서 Parent Component의 State로 올려서 저장까지 한번 해보겠습니다.

자식 Component에서 부모 Component으로 State 끌어올리기(Lift-up) 하기

우리는 방금전에 아주 간단한 Component 2개를 만들었었죠. 우리는 지금부터 여기에 Comment 라는 Input를 추가할 것이고, 이것을 상위 컴포넌트의 State에서 값을 저장하게 해보겠습니다.

// ChildComponent.js

export default ChildComponent = props = { // props를 파라미터로 받게 하고..
 return (
<div>
  <p>{props.id}</p> // 이렇게 사용할 수 있습니다.
<p>{props.content}</p> // 이렇게 하면 id, content가 나타나겠죠.
///////////////////////////////////////////
<div className="comment">
<input type="text" name="comment">
</div>
///////////////////////////////////////////
   </div>
)
}

이렇게 comment 라는 div 를 하나 추가했습니다.

Input 태그의 값이 변경되었을 때 ChildComponent 에 아래와 같이 처리하여 올릴 수 있습니다.

export default ChildComponent = props = { // props를 파라미터로 받게 하고..

// 1) 새로운 useState를 만들어줍니다.
const [comments, setComments] = useState();

// 3) onChange 를 정의해줍시다!
const onChange = event => {
// 요건.. event.target.name, event.target.value 로 정의할 수 있습니다!
const {name, value} = event.target;
   // setComments을 사용합니다!
   setComments({
    [name]: value // 이런 형태로 하면, 코드를 다시 쓰기 좋겠죠?
  });
   props.onChange(comments) // 4) 이렇게 상위 컴포넌트로 전달하면 됩니다.
}
 return (
<div>
  <p>{props.id}</p> // 이렇게 사용할 수 있습니다.
<p>{props.content}</p> // 이렇게 하면 id, content가 나타나겠죠.
///////////////////////////////////////////
<div className="comment">
// 2) onChange를 추가해줍니다.
<input type="text" name="comment" onChange={onChange} />
</div>
///////////////////////////////////////////
   </div>
)
}

이렇게 하고 상위 컴포넌트는 다음과 같이 처리해줍니다.

// ParentComponent.js
export default ParentComponent = () => {
 const [ stateValues, setStateValues ] = useState({
   id: 1,
   content: 'hello'
})
 
 return (
<ChildComponent id={stateValues.id} content={stateValues.content} onChange={value => setStateValues({...stateValues, ...value})} />
)
}

이렇게 하면 Child Component에서 Parent Component 로 전달할 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다