ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 240205_React
    카테고리 없음 2024. 2. 5. 16:47
    import React, { useState } from "react";
    
    function SignUp(props) {
      const [name, setName] = useState("");
      const [gender, setGender] = useState("비공개");
    
      const handleChangeName = (event) => {
        setName(event.target.value);
      }
    
      const handleChangeGender = (event) => {
        setGender(event.target.value);
      }
    
      const handleSubmit = (event) => {
        alert(`이름: ${name}, 성별:${gender}`);
        event.preventDefault();
      };
    
      return (
        <form onSubmit={handleSubmit}>
          <label>
            이름 : 
            <input type="text" value={name} onChange={handleChangeName}/>
          </label>
          <br/>
          <label>
            성별 :
            <select value={gender} onChange={handleChangeGender}>
              <option value="남자">남자</option>
              <option value="여자">여자</option>
              <option value="비공개">비공개</option>
            </select>
            </label>
          <button type="submit">제출</button>
        </form>
      );
    }
    export default SignUp;
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    // import App from './App'; 주석처리
    import reportWebVitals from './reportWebVitals';
    import SignUp from './chapter_11/SignUp';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <SignUp/>
      </React.StrictMode>
    );
    
    reportWebVitals();

    1. 상태 초기화:

    • useState를 사용하여 name 상태 변수를 초기화합니다. name은 현재 빈 문자열로 초기화됩니다.
    const [name, setName] = useState("");

    2. 입력 값 변경:

    • 입력란에 값을 입력할 때마다 handleChangeName 함수가 호출됩니다.
    • 입력 값이 변경될 때마다 setName을 통해 name 상태가 업데이트됩니다.
    const handleChangeName = (event) => {
        setName(event.target.value);
      }

    3. 폼 제출:

    • 폼이 제출되면 handleSubmit 함수가 호출됩니다.
    • alert 창이 팝업되며 "이름: 익명의 하마"라는 메시지가 표시됩니다.
    const handleSubmit = (event) => {
        alert(`이름: ${name}`);
        event.preventDefault();
      };

    4. 페이지 갱신 방지:

    • event.preventDefault()를 호출하여 기본 제출 동작을 방지합니다. 이로써 페이지가 새로고침되지 않고 상태가 유지됩니다.

    5. 렌더링:

    • 최종적으로 폼 요소가 화면에 렌더링되고, 사용자가 입력한 값에 따라 화면이 업데이트됩니다.


     

    const scaleNames = {
      c: "섭씨",
      f: "화씨",
    };
    
    function TemperatureInput(props) {
      const handleChange = (event) => {
        props.onTemperatureChange(event.target.value);
      };
    
      return (
        <fieldset>
          <legend>온도를 입력해주세요 (단위:{scaleNames[props.scale]}):</legend>
          <input value={props.temperature} onChange={handleChange}></input>
        </fieldset>
      );
    }
    
    export default TemperatureInput;
    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;
    }
    
    function tryConvert(temperature, convent) {
      const input = parseFloat(temperature);
      if(Number.isNaN(input)) {
        return "";
      }
      const output = convent(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>
          <TemperatureInput
            scale="c"
            temperature={celsius}
            onTemperatureChange={handleCelsiusChange}
          ></TemperatureInput>
          <TemperatureInput
            scale="f"
            temperature={fahrenheit}
            onTemperatureChange={handleFahrenheitChange}></TemperatureInput>
          <BoilingVerdict celsius={parseFloat(celsius)}></BoilingVerdict>
        </div>
      );
    }
    
    export default Calculator;
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import reportWebVitals from './reportWebVitals';
    
    import Calculator from './chapter_12/Calculater';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <Calculator/>
      </React.StrictMode>
    );
    
    reportWebVitals();

    1. 사용자가 "섭씨" 입력 필드에 100을 입력합니다.
    2. TemperatureInput 컴포넌트의 <input> 엘리먼트에서 onChange 이벤트가 발생합니다.
    3. handleChange 함수가 호출되어 사용자가 입력한 값(100)이 이벤트 객체에서 추출됩니다.
    4. props.onTemperatureChange(event.target.value)를 통해 상위 컴포넌트인 Calculator의 handleCelsiusChange 함수가 호출됩니다.
    5. handleCelsiusChange 함수는 입력된 섭씨 온도(100)를 setTemperature 함수를 통해 상태로 설정하고, 동시에 온도의 단위를 "섭씨"로 설정합니다.
    6. useState 훅에 의해 상태가 변경되면 React는 해당 컴포넌트를 리렌더링합니다.
    7. Calculator 컴포넌트가 리렌더링되면서 섭씨 온도(100)에 따른 화씨 온도가 계산됩니다.
    8. tryConvert 함수에서 toFahrenheit 함수가 호출되어 섭씨 온도(100)가 화씨 온도로 변환됩니다.
    9. 변환된 화씨 온도가 상태로 설정되고, useState에 의해 컴포넌트가 다시 리렌더링됩니다.
    10. TemperatureInput 컴포넌트가 화씨 온도를 표시하고, 이벤트 핸들러는 handleFahrenheitChange 함수를 호출합니다.
    11. BoilingVerdict 컴포넌트는 섭씨 온도(100)를 전달받아 물이 끓는지 여부를 확인하고 그에 따라 "물이 끓습니다." 또는 "물이 끓지 않습니다." 메시지를 표시합니다.
    12. 사용자는 변환된 화씨 온도를 "화씨" 입력 필드에서 확인할 수 있습니다.

     


    function card(props){
      const {title, backgroundColor, children } = props;
      return (
        <div 
          style={{
            margin: 8,
            padding: 8,
            borderRadius: 8,
            boxShadow: "0px 0px 4px grey",
            backgroundColor: backgroundColor || "white",
          }}
          >
            {title && <h1>{title}</h1>}
            {children}
          </div>
      );
    }
    
    export default card;
    function card(props){
      const {title, backgroundColor, children } = props;
      return (
        <div 
          style={{
            margin: 8,
            padding: 8,
            borderRadius: 8,
            boxShadow: "0px 0px 4px grey",
            backgroundColor: backgroundColor || "white",
          }}
          >
            {title && <h1>{title}</h1>}
            {children}
          </div>
      );
    }
    
    export default card;
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import reportWebVitals from './reportWebVitals';
    import ProfileCard from './chapter_13/ProfileCard';
    
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <ProfileCard/>
      </React.StrictMode>
    );
    
    reportWebVitals();

    1. ProfileCard 컴포넌트가 렌더링되면 함수 컴포넌트가 호출됩니다.
    2. ProfileCard 컴포넌트 안에서 <Card> 컴포넌트가 JSX로 사용되었습니다.
    3. <Card> 컴포넌트에 title prop으로 "Hama"가 전달되었고, backgroundCorlor prop으로 "4ea04e"가 전달되었습니다. (주의: 오타가 있어서 backgroundCorlor를 backgroundColor로 수정해야 합니다.)
    4. <Card> 컴포넌트에서는 전달받은 props를 비구조화하여 사용합니다. title, backgroundColor, 그리고 children으로 분리합니다.
    5. <Card> 컴포넌트는 <div> 요소를 반환합니다. 이 <div>은 스타일이 적용된 박스로, margin, padding, borderRadius, boxShadow, 그리고 backgroundColor 스타일이 설정되어 있습니다.
    6. title이 존재하는 경우, <h1> 요소가 렌더링되어 "Hama"라는 텍스트가 표시됩니다.
    7. <Card> 컴포넌트의 children으로 전달된 내용이 렌더링되어 "안녕하세요, 물먹는 하마입니다."와 "저는 리액트를 사용해서 개발하고 있습니다."가 텍스트로 표시됩니다.
    8. 따라서, 최종적으로 화면에는 스타일이 적용된 "Hama"라는 제목과 두 문장이 포함된 하마 프로필 카드가 표시됩니다.

    import { useContext } from "react";
    import ThemeContext from "./ThemeContext";
    
    function MainContent(props) {
      const {theme, toggleTheme} = useContext(ThemeContext);
    
      return (
        <div
          style={{
            width:"100vw",
            height:"100vh",
            padding:"1.5rem",
            backgroundColor: theme == "light" ? "white" : "black",
            color: theme == "light" ? "black" : "white",
          }}
          >
            <p>안녕하세요, 테마 변경이 가능한 웹사이트 입니다.</p>
            <button onClick={toggleTheme}>테마 변경</button>
          </div>
      );
    }
    export default MainContent;
    import { useState, useCallback } from "react";
    import ThemeContext from "./ThemeContext";
    import MainContent from "./MainContent";
    
    function DarkOrLight(props) {
      const [theme, setTheme] = useState("light");
      const toggleTheme = useCallback(() => {
        if (theme === "light"){
          setTheme("dark");
        }else if (theme === "dark"){
          setTheme("light");
        }
      }, [theme]);
    
      return (
        <ThemeContext.Provider value = {{ theme, toggleTheme }}>
          <MainContent/>
        </ThemeContext.Provider>
      );
    }
    
    export default DarkOrLight;
    import React from "react";
    
    const ThemeContext = React.createContext();
    ThemeContext.displayName = "ThemeContext";
    
    export default ThemeContext;
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    
    import reportWebVitals from './reportWebVitals';
    import DarkOrLight from './chapter_14/DarkOrLoght';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <DarkOrLight/>
      </React.StrictMode>
    );
    
    reportWebVitals();
    1. DarkOrLight 컴포넌트가 렌더링되면 theme 상태와 toggleTheme 함수가 초기값과 함께 생성됩니다. 초기값으로는 "light" 테마가 설정되어 있습니다.
    2. DarkOrLight 컴포넌트는 ThemeContext.Provider로 감싸져 있습니다. value prop으로는 현재의 theme 상태와 toggleTheme 함수가 제공됩니다.
    3. MainContent 컴포넌트가 ThemeContext.Provider에 의해 제공된 theme 상태와 toggleTheme 함수를 가져와서 useContext를 통해 사용합니다.
    4. MainContent 컴포넌트는 <div> 요소를 반환하고, 해당 요소의 스타일은 현재의 theme 값에 따라 동적으로 변경됩니다.
      • 만약 theme이 "light"이면, 배경색은 흰색("white"), 글자색은 검정색("black")으로 설정됩니다.
      • 만약 theme이 "dark"이면, 배경색은 검정색("black"), 글자색은 흰색("white")으로 설정됩니다.
    5. <div> 요소 안에는 "안녕하세요, 테마 변경이 가능한 웹사이트 입니다."라는 문장과 "테마 변경" 버튼이 포함되어 있습니다.
    6. "테마 변경" 버튼을 클릭하면, 해당 버튼에 등록된 onClick 이벤트 핸들러인 toggleTheme 함수가 호출됩니다.
    7. toggleTheme 함수는 현재의 theme 상태값을 확인하고, "light"이면 "dark"로, "dark"이면 "light"로 변경하여 setTheme을 통해 상태를 갱신합니다.
    8. setTheme 함수에 의해 theme 상태가 변경되면, DarkOrLight 컴포넌트가 다시 렌더링되어 ThemeContext.Provider가 새로운 theme 값과 toggleTheme 함수를 제공합니다.
    9. MainContent 컴포넌트는 useContext를 통해 새로운 theme 값과 toggleTheme 함수를 가져오고, 이에 따라 동적으로 변경된 스타일이 반영된 새로운 화면이 렌더링됩니다.
    10. 이렇게 사용자가 "테마 변경" 버튼을 클릭할 때마다, 테마에 따라 배경색과 글자색이 전환되어 보이는 효과를 가진 테마 변경이 가능한 웹사이트가 만들어집니다.

Designed by Tistory.