react에서 styled components 사용시 input tag에서 focus를 잃어버리는 문제

최재용·2020년 1월 15일
5
post-custom-banner

react에서 styled components를 적용하기 시작하였습니다.

styled components를 input tag에 적용하여 사용하던 도중 input의 onChange()함수에서 state를 변경하였습니다.

하지만 컴포넌트에서 매 입력시마다 input에서의 focus를 잃어버리는 일이 발생하였는데요.

그 원인과 해결에 대하여 기록합니다.

1. 오류 상황

해당 컴포넌트에서 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를 잃어버리는 결과가 발생합니다.

2. 해결방법

해결방법은 간단합니다. 아래처럼 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}
    />
  );
}

코드 실행은 여기에서 확인하시면 됩니다.

profile
개발 로그
post-custom-banner

4개의 댓글

comment-user-thumbnail
2020년 1월 17일

위의 오류는 Custom Hooks로 따로 연결해주어도 오류가 발생하지 않습니다~

답글 달기
comment-user-thumbnail
2020년 1월 27일

정말 감사합니다. 이유 못찾고 해메고 있었는데.ㅜ

답글 달기
comment-user-thumbnail
2021년 11월 16일

와 진자 감사합니다 ㅠㅠㅠㅠ

답글 달기
comment-user-thumbnail
2023년 5월 7일

와 진짜 감사합니다 이 댓글 쓰려고 가입했어요

답글 달기