react에서 styled components를 적용하기 시작하였습니다.
styled components를 input tag에 적용하여 사용하던 도중 input의 onChange()함수에서 state를 변경하였습니다.
하지만 컴포넌트에서 매 입력시마다 input에서의 focus를 잃어버리는 일이 발생하였는데요.
그 원인과 해결에 대하여 기록합니다.
해당 컴포넌트에서 useState()를 사용하여 onChange() 시에 state를 변경하게 되었습니다.
다음과 같은 코드에서 오류가 발생하게 되었습니다.
import React, { useState } from "react";
import styled from "styled-components";
export default function App() {
const InputField = styled.input``;
const [username, setUsername] = useState("");
const onChangeField = e => {
setUsername(e.target.value);
};
return (
<InputField
type="text"
name="username"
value={username}
onChange={onChangeField}
/>
);
}
실행은 여기에서 확인하시면 됩니다.
위의 코드를 실행해보면 매 입력시마다 input의 focus를 잃어버리는데요.
리액트 컴포넌트에서는 state 값이 변경될때마다 매번 컴포넌트의 리렌더링이 발생합니다.
(여기에서는 textarea 입력시 onChange함수로 인해 useState로 생성한 username이 계속 변경됨. 따라서 해당 컴포넌트는 입력시마다 리렌더링 대상이 됩니다.)
const InputField = styled.div``;
위의 코드가 컴포넌트 내부에 존재하기 때문에 리랜더링을 할 때마다 해당 input도 다시 생성되고 input의 focus를 잃어버리는 결과가 발생합니다.
해결방법은 간단합니다. 아래처럼 styled components를 컴포넌트 밖에 선언해주시면 됩니다.
import React, { useState } from "react";
import styled from "styled-components";
const InputField = styled.input``;
export default function App() {
const [username, setUsername] = useState("");
const onChangeField = e => {
setUsername(e.target.value);
};
return (
<InputField
type="text"
name="username"
value={username}
onChange={onChangeField}
/>
);
}
코드 실행은 여기에서 확인하시면 됩니다.
위의 오류는 Custom Hooks로 따로 연결해주어도 오류가 발생하지 않습니다~