React - 07

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

React

목록 보기
11/11

App7.jsx + folder5

부모컴포넌트의 값을 자식컴포넌트에서 변경하기

TemperatureInput.jsx

// TemperatureInput.jsx

import React from "react";

const scaleNames = {
  c: "섭씨",
  f: "화씨",
};

function TemperatureInput(props) {

  // input 태그의 값 변경 이벤트 발생 시 동작할 함수, event 객체를 매개변수로 가져옴
  const handleChange = (e) => {
    // 부모 컴포넌트에서 전달받은 props 중 키 이름이 onTemperatureChange 인 함수를 실행
    // onTemperatureChange 함수는 부모 컴포넌트의 state 값을 수정하는 함수임(자식 컴포넌트의 데이터 부모 컴포넌트로 전달)
    props.onTemperatureChange(e.target.value);
  };

  return (
    <fieldset>
      <legend>
        온도를 입력해주세요 (단위 : {scaleNames[props.scale]})
      </legend>
      {/* onChange 는 input 태그의 값 변경시 발생하는 이벤트, 해당 이벤트에 handleChange 라는 함수를 연동 */}
      <input value={props.temperature} onChange={handleChange}/>
    </fieldset>
  );
}

export default TemperatureInput;

Calculator.jsx

// Calculator.jsx
import React, {useState} from "react";
import TemperatureInput from "./TemperatureInput";

function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>물이 끓습니다.</p>;
  }
  return <p>물이 끓지 않습니다.</p>;
}

// 매개변수로 화씨 온도를 받아서 섭씨 온도로 변환
function toCelsius(fahrenheit) {
  return ((fahrenheit - 32) * 5) / 9;
}

// 매개변수로 섭씨 온도를 받아서 화씨 온도로 변환
function toFahrenheit(celsius) {
  return (celsius * 9) / 5 + 32;
}

// 매개변수로 현재 온도와 온도 변환을 위한 함수(convert)를 받아서 사용
function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  // 입력받은 온도가 숫자인지 아닌지 확인, 숫자가 아니면 빈 문자열 "" 반환
  if (Number.isNaN(input)) {
    return "";
  }

  // 두번째 매개변수로 받은 변환함수(convert) 를 사용하여 표시 온도를 변환
  const output = convert(input);
  // 수학 관련 함수를 사용하여 소수점 이하 부분 처리(반올림)
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();

}

function Calculator(props) {
  const [temperature, setTemperature] = useState('');
  const [scale, setScale] = useState('C');

  const handleCelsiusChange = (temperature) => {
    setTemperature(temperature);
    setScale('c');
  };

  const handleFahrenheitChange = (temperature) => {
    setTemperature(temperature);
    setScale('f');
  };

  // 현재 온도를 표시방식에 따라서 변환
  const celsius = scale === 'f' ? tryConvert(temperature,  toCelsius) : temperature;
  const fahrenheit = scale === 'c' ? tryConvert(temperature,  toFahrenheit) : temperature;

  return (
    <div>
      {/* 자식 컴포넌트 호출 시 props에 2개의 데이터와 state 의 값을 변경할 수 있는 함수를 제공 */}
      <TemperatureInput scale={'c'} temperature={celsius} onTemperatureChange={handleCelsiusChange} />
      <TemperatureInput scale={'f'} temperature={fahrenheit} onTemperatureChange={handleFahrenheitChange} />
      {/* 온도를 props 를 통해서 전달, 실수로 표현하기 위해서 parseFloat() 사용 */}
      <BoilingVerdict celsius={parseFloat(celsius)} />
    </div>
  );
}

export default Calculator;

App7.jsx

import React from "react";
import Calculator from "./folder5/Calculator";

function App7() {
  return (
    <div>
     <Calculator />
    </div>
  );
}

export default App7;
  • 80 일때
  • 100 일때

컨텍스트

앱(theme 데이터) - 툴바(theme 데이터) - 테마버튼(theme 데이터) - Button(theme 데이터) 으로 값이 전달되어 dark 가 반영이 됨

컨텍스트 사용 X

App.jsx

// folder5/App.jsx

import React from "react";
import Toolbar from "./Toolbar";

function App(props) {
  // 자식 컴포넌트에 theme 라는 이름으로 데이터("dark")를 전달
  return <Toolbar theme={"dark"}/>
}

export default App;

Toolbar.jsx

// folder5/Toolbar.jsx

import React from "react";
import ThemedButton from "./ThemedButton";

function Toolbar(props) {
  return (
    <div>
      {/* 자식 컴포넌트로 theme 라는 이름의 데이터를 전달 */}
      <ThemedButton theme={props.theme} />
    </div>
  );
}

export default Toolbar;

ThemeButton.jsx

// folder5/ThemedButton.jsx

import React from "react";
const styles = {
  bg: {
    background: "white",
  }
}

function Button(props) {
  // 부모에게서 전달받은 theme 를 사용하고 있음
  if (props.theme == "dark") {
    styles.bg.background = 'black';
  }
  else {
    styles.bg.background = 'red';
  }
  return <button style={styles.bg}>테마 적용 버튼</button>
}

function ThemedButton(props) {
  return (
    // 자식 컴포넌트로 theme 를 전달
    <Button theme={props.theme}/>
  );
}

export default ThemedButton;

App7.jsx

import React from "react";
import Calculator from "./folder5/Calculator";
import Toolbar from "./folder5/Toolbar";
import App from "./folder5/App";

function App7() {
  return (
    <div>
     <Calculator />
      <App/>
    </div>
  );
}

export default App7;

컨텍스트 사용 O

App2.jsx

// folder5/ThemeContext.jsx
// folder5/MainContent.jsx
// folder5/DarkOrLight.jsx

리액트 라우터 DOM

https://reactrouter.com/en/main
최신버전 : 6.6.1

  • 자주 사용하는건 BrowserRouter, Router
  • 터미널에서 라우터 설치

pages 경로 추가

App7.jsx 에 코드 추가

import {BrowserRouter, Routes, Route} from "react-router-dom";

, return 내부 주석처리 후 코드 추가

import React from "react";
import Calculator from "./folder5/Calculator";
import Toolbar from "./folder5/Toolbar";
import App from "./folder5/App";
import App2 from "./folder5/App2";
import MainContent from "./folder5/MainContent";
import DarkOrLight from "./folder5/DarkOrLight";
import App4 from "./folder5/App4";

import {BrowserRouter, Routes, Route} from "react-router-dom";

function App7() {
  return (
    // <div>
    //  <Calculator />
    //   <App/>
    //   <hr/>
    //   <App2/>
    //   <hr/>
    //   <DarkOrLight/>
    //   <App4/>
    // </div>
    <BrowserRouter>
      <Routes>
        <Route>
          
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App7;

Layout.jsx

Home.jsx

0개의 댓글