비슷한 state들 한번에 관리하기!

이현섭·2022년 7월 2일
0
post-custom-banner

📌 비슷한 state와 함수들을 한번에 관리하기!

const [author, setAuthor] = useState("")
const [content, setContent] = useState("")

return (
    <div>
        <input
            name='author' 
            type="text" 
            value={author}
            onChange={(e) => {
                setAuthor(e.target.value)
            }}
        />
        <textarea 
            name='content'
            value={content}
            onChange={(e) => {
                setContent(e.target.value)
            }}
        />
    </div>

현재 어떠한 컴포넌트 안에 2개의 state와 input 태그 textarea 태그가 있다고 생각하자. 현재 이 2개의 태그는 동작방식이 유사하다. change 이벤트가 발생하였을때 콜백함수도 유사하게 동작한다. 지금은 2개여서 코드 반복이 2번밖에 일어나지 않지만 만약 10개 이런식으로 넘어간다면 같은 코드가 계속 반복되게 된다.

📌 1. state먼저 줄이자!

const [state, setState] = useState({
    author : "",
    content : ""
})

하나의 state안에 초기값을 객체로 만들어 author와 content라는 키 값으로 빈값을 초기값으로 설정해 주었다.

이 상태에서도 현재는 state값이 2개여서 간단하지만 만약 10개라면 관리해야 하는 state값들이 많아질 것이다. 이러한 경우 setState를 통해 다시 작성해줘야 하는 state의 key와 value 값이 여러개가 된다.
=> 스프레드 연산자를 활용하자!

📌 2. spread 연산자 활용

우선 spread 연산자를 사용하지 않는다고 생각해보자.
아래와 같이 state값이 많아질경우 setState에서 관리해줘야 할 값들이 많아진다.

<input
    name='author' 
    type="text" 
    value={author}
    onChange={(e) => {
        setState({
            author : e.target.value,
            content : state.content,
          	3번째 : state.3번째,
          	4번째 : state.4번째,
          	5번째 : state.5번째, .....
        })
    }}
/>

여기서 spread 연산자를 이용한다면?
아래와 같이 코드의 반복성이 크게 줄어든다.

<input
    name='author' 
    type="text" 
    value={author}
    onChange={(e) => {
        setState({
            ...state,
            author : e.target.value
        })
    }}
/>
<textarea 
    name='content'
    value={content}
    onChange={(e) => {
        setState({
            ...state,
            content : e.target.value
        })
    }}
/>

🔥 주의
이전의 state먼저 펼쳐 줘야 우리가 변경하고자 하는 state값들이 순서에 맞게 변경된다.

반복성이 크게 줄었지만, 여기서 또 onChange의 콜백함수 또한 계속 반복됨을 알 수 있다. 따라서 이 onChange 함수도 handleChangeState함수로 선언해서 조금더 반복성을 줄여보자.

📌 3. e.target.name 을 활용

const handleChangeState = (e) => {
    setState({
        ...state,
        [e.target.name] : e.target.value
    })
}

return (
    <div>
        <input
            name='author' 
            type="text" 
            value={author}
            onChange={handleChangeState}
        />
        <textarea 
            name='content'
            value={content}
            onChange={handleChangeState}
        />
    </div>
)

onChange의 콜백함수로 handleChangeState를 넘겨주고
handleChangeState함수에서는 e.target.name 속성을 사용해주었다.
input 태그와 textarea 태그에는 name 값은 state의 키값과 동일하게 설정해 주었기 때문에 이벤트가 발생하였을때 우리가 변경하고자 하는 state의 값과 동일한 값을 변경할 수 있다.

📌 input태그에서 value={} 속성을 주는 이유

const [author, setAuthor] = useState("")
<input type="text" value={author}/>

이 상태에서는 input의 초기값이 빈값으로 고정되어있기 때문에 입력을 아무리 해줘도 value의 값이 변화하지 않는다. 즉, useState에 의해서만 변한다.

input 태그에 value를 넣어주면, 컴포넌트의 state가 내용을 제어하지만, value를 넣어주지 않으면 브라우저(DOM)가 자체적으로 내용을 제어

profile
안녕하세요. 프론트엔드 개발자 이현섭입니다.
post-custom-banner

0개의 댓글