[TIL16] React로 조건 만족시 로그인버튼 활성화하기

🚀·2021년 5월 8일
2

react

목록 보기
2/7
post-thumbnail


id의 형식이나 비밀번호의 글자수가 어떤 조건을 만족시 이렇게 로그인 버튼을 활성화하는 기능을 구현해보자!

🔍 구현할 사항

✔️ 입력한 아이디가 비밀번호 기준에 맞는 경우에만 로그인 버튼 색상 활성화
ID는 @ 포함 / PW는 5글자 이상 입력시
삼항연산자 사용


📚 과정

1. Button의 state값 지정하기

  1. 부모 컴포넌트인 Login에서 Button태그의 상태값을 먼저 지정한다.
    class Login extends React.Component {
      constructor() {
        super();
        this.state = {
          inputValue: { idValue: '', pwValue: '' },
          isButtonOn: false,     // 💡
        };
      }

isButtonOnfalse라는 Boolean형태의 값이다.


2. id,pw value가 조건 만족시 setState로 상태값 변경하는 함수 만들기

  handleAbleButton = () => {
    this.setState({
      isButtonOn:
        this.state.inputValue.idValue.includes('@') &&
        this.state.inputValue.pwValue.length >= 8, //위조건을 만족시 true리턴
    });
  };

handleAblebutton 함수는 id, pw의 validation을 확인해 조건이 맞다면 state값을 true로 바꾼다.

여기서 단축 평가 논리계산법을 이용해

if(button.inputValue.idValue.includes('@') && buttonOn.inputValue.pwValue.length >= 8){
  return true;
}

의 코드를

buttonOn.inputValue.idValue.includes('@') &&
        buttonOn.inputValue.pwValue.length >= 8

로 줄일수 있다.

단축평가논리계산법은 여기서 더 알아보자!


3. 위의 함수와 input창 연결하기

현재 handleAblebutton 함수를 정의해주었지만 이게 언제 실행될지는 아직 정하지 않았다!
우리는 이것을 input의 값이 들어올때마다 함수를 실행시켜 조건을 만족하는지 확인하고 만족시 state값을 변경해줄 것이다.

사실 이 함수는 배우지 않은 내용인데 착한 선배님께서 알려주셔서 알게되었다...ㅎㅎㅎㅎㅎㅎㅎ

  componentDidUpdate(prevProps, prevState) {
    if (this.state.inputValue !== prevState.inputValue) {
      this.handleAbleButton();
    }
  }

componentDidUpdate함수에 대해 먼저 알아보자!

  • componentDidUpdate함수state가 변경되면 호출된다!
  • 하지만 최초 렌더링에서는 호출되지 않는다.
  • 컴포넌트가 갱신되었을때 DOM을 조작하기 위해 이 메서드를 활용하면 좋다.
  • 또 이전과 현재의 props를 비교해 네트워크 요청을 보내는 작업도 이 메서드에서 이루어진다.
  • 대신 이 함수를 쓸 때 주의해야 할 점이 있는데 조건을 설정해주어야 한다는 것이다!
    만약, 조건을 설정하지 않고 실행하고 싶은 내용을 넣고 그게 setState하게 되면 state가 또 업데이트 되고 그러면 또 state가 업데이트 되기 때문에 이런식으로 무한루프에 빠진다.
    그래서 조건이 항상 필요하다.
  • componentDidUpdate함수는 두 개의 인자를 받아오는데 첫 번째 인자는 이전의 props값, 두 번째인자는 이전의 state값이다. 순서가 있기때문에 만약 이전의 props값을 사용하지 않더라도 첫 번째에는 넣어준다!

따라서 위의 함수는 만약 inputValuestate값이 이전의 state와 변경 될 때 handleAbleButton을 호출한다.

if (this.state.inputValue !== prevState.inputValue) { // this.state가 이전의 state값과 같지 않다면 실행!
      this.handleAbleButton();

4. className으로 버튼 색상 변경해주기

위의 과정들을 거쳐서 isButtonOnstatetrue로 변경되었다면 이제 버튼의 색상을 변경해주자!

  1. Button컴포넌트에 isButtonOn의 값을 changeColor라는 props로 전달해준다.

부모 컴포넌트 Login

  render() {
    return (
      <div className="loginSection">
        <header>Westagram</header>
        <InputId getInput={this.handleInput} />
        <Button
          idValue={this.state.inputValue.idValue}
          pwValue={this.state.inputValue.pwValue}
          changeColor={this.state.isButtonOn}  // ❗️❗️❗️❗️
        />
        <footer>비밀번호를 잊으셨나요?</footer>
      </div>
    );
  }
}
  1. 전달해준 props를 통해 button태그의 class이름을 각각 달리하여 동적으로 변하게 해준다.
    (이 때 미리 각 class이름에 button색상을 css로 넣어준다.)

자식 컴포넌트 Button

render() {
    return (
      <button
        className={this.props.changeColor ? 'changeColorBtn' : 'loginBtn'>
        로그인
      </button>
    );
  }

💡 Refactoring

1. 구조분해할당 하기

객체의 속성값을 분해하여 바로 변수에 선언해주는 구조 분해 할당을 이용해보자!

  handleAbleButton = () => {
    this.setState({
      isButtonOn:
        this.state.inputValue.idValue.includes('@') &&
        this.state.inputValue.pwValue.length >= 8, //위조건을 만족시 true리턴
    });
  };

의 코드는

handleAbleButton = () => {
  const { inputValue } = this.state;  ❗️❗️❗️❗️
  this.setState({
    isButtonOn:
      inputValue.idValue.includes('@' && '.') &&
      inputValue.pwValue.length >= 8, //위조건을 만족시 true리턴
  });
};

이렇게!!
또...

  render() {
    return (
      <div className="loginSection">
        <header>Westagram</header>
        <InputId getInput={this.handleInput} />
        <Button
          idValue={this.state.inputValue.idValue}
          pwValue={this.state.inputValue.pwValue}
          changeColor={this.state.isButtonOn}  
        />
        <footer>비밀번호를 잊으셨나요?</footer>
      </div>
    );
  }
}

의 코드는...

render() {
    const { inputValue, isButtonOn } = this.state;  // ❗️❗️❗️
    return (
      <div className="loginSection">
        <header>Westagram</header>
        <InputId getInput={this.handleInput} />
        <Button
          idValue={inputValue.idValue}
          pwValue={inputValue.pwValue}
          changeColor={isButtonOn}
        />
        <footer>비밀번호를 잊으셨나요?</footer>
      </div>
    );
  }
}

이렇게 바꿔준다 !!

🔑 완성된 코드

✔️ 부모 컴포넌트 Login

import React from 'react';
import InputId from './Components/InputId/InputId';
import Button from './Components/Button/Button';
import './Login.scss';
//
class Login extends React.Component {
  constructor() {
    super();
    <this.state = {
      inputValue: { idValue: '', pwValue: '' },
      isButtonOn: false,
    };
  }
//
  handleInput = e => {
    const { name, value } = e.target;
    this.setState({
      inputValue: { ...this.state.inputValue, [name]: value },
    });
  };
//
  handleAbleButton = () => {
    const { inputValue } = this.state;
    this.setState({
      isButtonOn:
        inputValue.idValue.includes('@' && '.') &&
        inputValue.pwValue.length >= 8, //위조건을 만족시 true리턴
    });
  };
//
  componentDidUpdate(prevProps, prevState) {
    if (this.state.inputValue !== prevState.inputValue) {
      this.handleAbleButton();
    }
  }
//
  render() {
    const { inputValue, isButtonOn } = this.state;
    return (
      <div className="loginSection">
        <header>Westagram</header>
        <InputId getInput={this.handleInput} />
        <Button
          idValue={inputValue.idValue}
          pwValue={inputValue.pwValue}
          changeColor={isButtonOn}
        />
        <footer>비밀번호를 잊으셨나요?</footer>
      </div>
    );
  }

✔️ 자식 컴포넌트 Button

import React from 'react';
import './Button.scss';
//
class Button extends React.Component {
  render() {
    return (
      <button
        className={this.props.changeColor ? 'changeColorBtn' : 'loginBtn'}

        로그인
      </button>
    );
  }
}
//
export default Button;

0개의 댓글