React - 06

월요일좋아·2023년 5월 10일
0

React

목록 보기
10/11

App6.jsx + folder4

공부할때 유용한 사이트 : https://www.w3schools.com/react/default.asp

조건부 렌더링

어떠한 조건에 따라서 화면에 표시할 렌더링이 달라지는 것
if 문 사용 시 render() 함수가 동작되는 return 부분에서 조건문을 사용하는 것이 아니라 return 밖에서 조건문을 사용하고 return 안에서는 삼항 연산자를 사용함

자바스크립트의 true / false

  • true : 논리형 true, 빈 object 타입 {}, 빈 배열 [], 0이 아닌 숫자, 빈 문자열이 아닌 문자열
  • false : 논리형 false, 숫자 0 또는 0.0, 빈 문자열 '', "", ` `, null, undefined, NaN(Not a Number)
    Goal.jsx
// folder4/Goal.jsx

import React from "react";
import MadeGoal from "./MadeGoal";
import MissedGoal from "./MissedGoal";

function Goal(props) {
  const isGoal = props.isGoal;

  // if 문은 return 부분 바깥에서 걸어줘야함. return 안에서 진행하려면 삼항연산자 사용.
  if (isGoal) {
    return <MadeGoal/>
  }

  return <MissedGoal/>

}

export default Goal;

MadeGoal.jsx

// folder4/MadeGoal.jsx

import React from "react";

function MadeGoal() {
  return (
    <h1>GOAL!!</h1>
  );
}

export default MadeGoal;

MissedGoal.jsx

// folder4/MissedGoal.jsx

import React from "react";

function MissedGoal() {
  return (
    <h1>MISSED!!</h1>
  );
}

export default MissedGoal;


LoginControl.jsx

// folder4/LoginControl.jsx

import React, {useState} from "react";
import button from "bootstrap/js/src/button";
import Greeting from "./Greeting";
import UserStatus from "./UserStatus";


function LoginButton(props) {
  return (
    <button onClick={props.onClick} type={"button"} className={"btn btn-info"}>로그인</button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick} type={"button"} className={"btn btn-danger"}>로그아웃</button>
  );
}


function LoginControl() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const handleLoginClick = () => {
    setIsLoggedIn(true);
  }

  const handleLogoutClick = () => {
    setIsLoggedIn(false);
  }

  // 엘리먼트 변수 : 자바스크립트 변수에 리액트 컴포넌트를 저장한 것
  // 조건부 렌더링을 사용하기 위해서 자바스크립트 변수 button 에 리액트 컴포넌트를 저장
  let button;

  // state 의 상태에 따라서 엘리먼트 변수에 저장될 리액트 컴포넌트를 변경
  if (isLoggedIn) {
    button = <LoginButton onClick={handleLogoutClick}/>
  }
  else {
    button = <LogoutButton onClick={handleLoginClick}/>
  }

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn}/>
      {/* 엘리먼트 변수에 저장된 리액트 컴포넌트가 출력됨 */}
      {/*{button}*/}

      {/* 삼항 연산자 */}
      {
        isLoggedIn ? <LogoutButton onClick={handleLogoutClick}/> : <LoginButton onClick={handleLoginClick}/>
      }
      <UserStatus isLoggedIn={isLoggedIn}/>
    </div>
  );
}

export default LoginControl;

UserStatus.jsx

// folder4/UserStatus.jsx

import React from "react";
// 문제 1) 아래의 소스에서 삼항 연산자를 사용한 부분을 if ~ else 문을 사용하여 조건부 렌더링으로 수정하세요
function UserStatus(props) {

  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return (
      <div>
        이 사용자는 현재 <b>로그인</b> 상태입니다.
      </div>
    );
  }
    return (
      <div>
        이 사용자는 현재 <b>로그인하지 않은</b> 상태입니다.
      </div>
    );

  // 삼항연산자 사용 코드
  // return (
  // <div>
  //    이 사용자는 현재 <b>{props.isLoggedIn ? '로그인' : '로그인하지 않은'}</b> 상태입니다.
  // </div>
  // );
}

export default UserStatus;

Greeting.jsx

// folder4/Greeting.jsx

import React from "react";

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return <UserGreeting/>
  }
  return <GuestGreeting/>
}

function UserGreeting() {
  return (
    <h1>다시 오셨군요.</h1>
  );
}

function GuestGreeting() {
  return (
    <h1>회원 가입을 해주세요.</h1>
  );
}



export default Greeting;
  • 클릭 전
  • 클릭 후

inline if, &&

inLine if : jsx 문법으로 렌더링을 진행하는 render() 함수 내부에서 if 문을 사용할 수 없기 떄문에 '&&' 연산자를 사용하거나 삼항 연산자를 사용하여 조건부 렌더링을 진행할 수 있음
'&&'연산자 사용 시 주의점 : && 연산자 오른쪽에 있는 피연산자는 왼쪽에 있는 피연산자의 값에 따라 렌더링이 결정됨
&& 연산자 왼쪽의 피연산자 값이 false 일 경우 오른쪽의 피연산자는 아예 동작하지 않음.(=연산 평가 자체가 동작하지 않음)
&& 연산자 왼쪽의 피연산자는 false 일 때라도 연산 평가가 이루어지기 때문에 해당 값이 그대로 출력이 됨.

MailBox.jsx

// folder4/MailBox.jsx

import React from "react";

function MailBox(props) {
  const unreadMessages = props.unreadMessages;


  return (
    <div>
      <h1>안녕하세요</h1>
      <h3>inline if (&& 연산자 테스트)</h3>
      {
        unreadMessages > 0 &&
        <h2>
          현재 {unreadMessages} 개의 읽지 않은 메시지가 있습니다.
        </h2>
      }
    </div>
  );
}

export default MailBox;

MainPage.jsx

// folder4/MainPage.jsx

import React, {useState} from "react";
import WarningBanner from "./WarningBanner";

function MainPage() {
  const [showWarning, setShowWarning] = useState(false);

  const handleToggleClick = () => {
    setShowWarning(prevState => !prevState);
  }

  return (
    <div>
      <WarningBanner warning={showWarning}/>
      <button onClick={handleToggleClick} className={"btn btn-success"}>{showWarning ? '감추기' : '보이기'}</button>
    </div>
  )
}

export default MainPage;

WarningBanner.jsx

// folder4/WarningBanner.jsx

import React from "react";

/*
컴포넌트 렌더링 막기
- 리액트에서 렌더링을 하고 싶지 않을 경우 null 을 사용
*/
function WarningBanner({warning}) {
  // warning 이 false 일때 if 문 실행됨
  if (!warning) {
    return null;
  }

  return <div>경고!!</div>
}

export default WarningBanner;
  • 클릭 전
  • 클릭 후

자식 1-1 에서 2-2 로 바로 데이터 이동 불가능.
이것을 가능하게 해주는것이 컨텍스트이다.

0개의 댓글