[React] onFocus 와 onBlur이벤트를 사용하여 인풋창 색상 변경하기

Cottonmycotton·2021년 12월 4일
5

React

목록 보기
6/14


로그인 페이지를 만드는 중 구현하기로 한 필수사항 중 인풋창을 클릭했을 때 밑줄 색이 바뀌고 인풋 바깥인 메인페이지를 다시 클릭했을 때 원래 색상으로 돌아오게 하는 기능이 있었다. 인풋창을 클릭할때마다 이벤트가 발생하는 토글 기능이 아닌 활성화된 기능을 다시 해제시켜야 하는 기능을 구현해야 했다.

1. onFocus

onFocus 이벤트는 엘리먼트(또는 자식 엘리먼트)가 포커스 될때 호출된다. 예를들어 텍스트 인풋을 클릭했을 때 호출된다.

<input onFocus={() => console.log('Focused on input')}

input창을 클릭했을 때 개발자도구에 'on focuesd on input' 이 찍히는 것을 확인할 수 있다.

2. onBlur

onBlur 이벤트는 엘리먼트(또는 자식 엘리먼트)에서 포커스가 사라졌을 때 호출된다. 예를 들어, 유저가 포커스된 텍스트 인풋의 바깥 영역을 클릭했을 때 호출된다.

<input onBlur={() => console.log('Triggered because this input lost focus')}

input의 바깥 창을 클릭했을 때 개발자도구에 'Triggered because this input lost focus'가 찍히는 것을 확인할 수 있다.

3. 코드 작성해보기

3-1. useState

이메일, 패스워드 둘 다 동일한 초기값과 함수를 가지기 때문에 객체를 사용하여 useState를 작성하였다. 불리언 값을 이용해 클래스네임을 변경해주려는 목적으로 초기값은 false로 설정하였다.

const [activeBorder, setActiveBorder] = userState({
  emailBorder: false,
  passwordBorder: false,
});

const { emailBorder, passwordBorder } = activeBorder;

3-2. 함수 & jsx 코드 $ scss

이벤트가 발생했을 때 값을 인자(border)로 받아와 값을 변경해주었다. onFocus가 될때 값을 true로 바꿔주고, onBlur가 될때 값을 false로 바꿔주었다. 그리고 값이 true일땐 클래스 네임을 'clickedInputBorder'로, false일 땐 'inputLine'으로 적용시켰다.

const handleFocusBorder = border => {
  setActiveBorder({
    ...activeBorder,
    [border]: false,
  });
};

const handleBlurBorder = border => {
  setActiveBorder({
    ...activeBorder,
    [border]: false,
  });
};

return (
  <main className="login">
  <form className="loginInput">
          <div className="emailInput">
            <div className="loginInputMassage">Email address *</div>
            <input
              name="email"
              className={emailBorder ? 'clickedInputLine' : 'inputLine'}
              onChange={handleInput}
              onFocus={() => handleFocusBorder('emailBorder')}
              onBlur={() => handleBlurBorder('emailBorder')}
            />
          </div>
          <div className="passwordInput">
            <div className="loginInputMassage">Password *</div>
            <input
              name="password"
              className={passwordBorder ? 'clickedInputLine' : 'inputLine'}
              onChange={handleInput}
              onFocus={() => handleFocusBorder('passwordBorder')}
              onBlur={() => handleBlurBorder('passwordBorder')}
            />
          </div>
          <span className="forgotIDPassword line">
            Forgot your ID or password?
          </span>
        </form>
  </main>

// scss
.clickedInputLine {
      margin: 20px 0 30px 0;
      width: 350px;
      border-bottom: 2px solid #adc088;
    }

    .forgotIDPassword {
      margin-top: 25px;
      font-size: 17px;
      letter-spacing: 1px;
    }

참고 자료: React 공식문서

profile
투명인간

0개의 댓글