React(2)

안정태·2021년 5월 7일
0

Study

목록 보기
22/33

이벤트 처리하기

JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달 합니다.

React 엘리먼트의 이벤트 처리 방식은 DOM 엘리먼트의 방법과 유사하다. 다만 몇 가지 문법의 차이가 있다.

//함수 컴포넌트
function ActionLink(){
  function handleClicke(e){
  	e.preventDefault();
    console.log('The Link was clicked.');
  }
  
  return (
    <a href='#' onClick={handleClick}>
      Click me
    </a>
  )
}

//class 컴포넌트
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

JSX 콜백 안에서 this의 의미를 주의해야 한다. JS에서 클래스 메서드는 기본적으로 바인딩 되어 있지 않습니다. this.hadleClick을 바인딩 하지 않고 onClick에 전달하면 thisundefined가 된다.

만약 바인딩이 불편하다면 다음 두가지 방법으로 해결이 가능하다.

  • 퍼블릭 클래스 필드 문법
    handleClick = () => {...}
  • 콜백에 화살표 함수 사용
    <button onClick={() => this.handleClick()}>

콜백에 화살표 함수 사용 방법의 문제점은 렌더링 될 때마다 다른 콜백이 생성된다는 것이다. 때문에 가급적 퍼블릭 클래스 필드 문법사용을 권장한다.

이벤트 핸들러에 인자 전달하기

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

조건부 렌더링

엘리먼트 변수

엘리먼트를 저장하기 위해 변수를 사용할 수 있다. 출력의 다른 부분은 변하지 않은 채로 컴포넌트의 일부를 조건부로 렌더링 할 수 있다.

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

논리 && 연산자로 if를 인라인으로 표현하기

{ 조건식 && 참일 때 값 }

거짓일 때는 항상 false로 평가된다. 만약 조건이 false라면 React는 무시된다.

주의

render() {
  const count = 0;
  return (
    <div>
      { count && <h1>Messages: {count}</h1>}
    </div>
  );
}  // 이 경우 <div>0</div> 이 렌더에 반환된다.

조건부 연산자로 if-else구문 인라인으로 표현하기

{ 조건식 ? 참일 때 값 : 거짓일 때 값 }

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn
        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />
      }
    </div>
  );
}

조건이 너무 복잡하다면 컴포넌트를 분리하기 좋을 때 라는 것이다.

컴포넌트가 렌더링하는 것을 막기

가끔 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있을 수도 있다. 그때는 렌더링 결과를 출력하는 대신 null을 반환하면 해결할 수 있다.

리스트와 Key

React에서 리스트를 만드는 방법은 배열에 map()을 적용하여 만듭니다.

여러개의 컴포넌트 렌더링 하기

const arr = [/*인자들*/]
arr.map( (/*인자*/) => /*적용할 컴포넌트*/)

위 그림에서 보듯 있는 배열 자체에 map()을 적용해주기만 하면 된다. 그리고 map을 통해서 적용할 내용을 함수대신에 컴포넌트에 들어가게 해주면 리스트 작성이 훨씬 수월해진다.

기본 리스트 컴포넌트 : 일반적으로 컴포넌트 안에서 리스트를 렌더링 한다.

Key

Key는 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. 배열 내부의 엘리먼트에 지정해야한다.

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

단, 항목의 순서가 바뀔 수 있는 경우 key에 인덱스를 사용하는 것은 권장하지 않는다.

Key로 컴포넌트 추출하기

key는 주변 배열의 context에서만 의미가 있다.

map()함수 내부에 있는 엘리먼트에 key를 넣어주면 된다.

function ListItem(props) {
  // 여기에는 key를 지정할 필요가 없다.
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 배열 안에 key를 지정해야 한다.
    <ListItem key={number.toString()} value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Key는 형제 사이에서만 고유한 값이어야 한다.

말 그대로다.

profile
코딩하는 펭귄

0개의 댓글