-
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();
- 사용자가 "섭씨" 입력 필드에 100을 입력합니다.
- TemperatureInput 컴포넌트의 <input> 엘리먼트에서 onChange 이벤트가 발생합니다.
- handleChange 함수가 호출되어 사용자가 입력한 값(100)이 이벤트 객체에서 추출됩니다.
- props.onTemperatureChange(event.target.value)를 통해 상위 컴포넌트인 Calculator의 handleCelsiusChange 함수가 호출됩니다.
- handleCelsiusChange 함수는 입력된 섭씨 온도(100)를 setTemperature 함수를 통해 상태로 설정하고, 동시에 온도의 단위를 "섭씨"로 설정합니다.
- useState 훅에 의해 상태가 변경되면 React는 해당 컴포넌트를 리렌더링합니다.
- Calculator 컴포넌트가 리렌더링되면서 섭씨 온도(100)에 따른 화씨 온도가 계산됩니다.
- tryConvert 함수에서 toFahrenheit 함수가 호출되어 섭씨 온도(100)가 화씨 온도로 변환됩니다.
- 변환된 화씨 온도가 상태로 설정되고, useState에 의해 컴포넌트가 다시 리렌더링됩니다.
- TemperatureInput 컴포넌트가 화씨 온도를 표시하고, 이벤트 핸들러는 handleFahrenheitChange 함수를 호출합니다.
- BoilingVerdict 컴포넌트는 섭씨 온도(100)를 전달받아 물이 끓는지 여부를 확인하고 그에 따라 "물이 끓습니다." 또는 "물이 끓지 않습니다." 메시지를 표시합니다.
- 사용자는 변환된 화씨 온도를 "화씨" 입력 필드에서 확인할 수 있습니다.
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();
- ProfileCard 컴포넌트가 렌더링되면 함수 컴포넌트가 호출됩니다.
- ProfileCard 컴포넌트 안에서 <Card> 컴포넌트가 JSX로 사용되었습니다.
- <Card> 컴포넌트에 title prop으로 "Hama"가 전달되었고, backgroundCorlor prop으로 "4ea04e"가 전달되었습니다. (주의: 오타가 있어서 backgroundCorlor를 backgroundColor로 수정해야 합니다.)
- <Card> 컴포넌트에서는 전달받은 props를 비구조화하여 사용합니다. title, backgroundColor, 그리고 children으로 분리합니다.
- <Card> 컴포넌트는 <div> 요소를 반환합니다. 이 <div>은 스타일이 적용된 박스로, margin, padding, borderRadius, boxShadow, 그리고 backgroundColor 스타일이 설정되어 있습니다.
- title이 존재하는 경우, <h1> 요소가 렌더링되어 "Hama"라는 텍스트가 표시됩니다.
- <Card> 컴포넌트의 children으로 전달된 내용이 렌더링되어 "안녕하세요, 물먹는 하마입니다."와 "저는 리액트를 사용해서 개발하고 있습니다."가 텍스트로 표시됩니다.
- 따라서, 최종적으로 화면에는 스타일이 적용된 "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();
- DarkOrLight 컴포넌트가 렌더링되면 theme 상태와 toggleTheme 함수가 초기값과 함께 생성됩니다. 초기값으로는 "light" 테마가 설정되어 있습니다.
- DarkOrLight 컴포넌트는 ThemeContext.Provider로 감싸져 있습니다. value prop으로는 현재의 theme 상태와 toggleTheme 함수가 제공됩니다.
- MainContent 컴포넌트가 ThemeContext.Provider에 의해 제공된 theme 상태와 toggleTheme 함수를 가져와서 useContext를 통해 사용합니다.
- MainContent 컴포넌트는 <div> 요소를 반환하고, 해당 요소의 스타일은 현재의 theme 값에 따라 동적으로 변경됩니다.
- 만약 theme이 "light"이면, 배경색은 흰색("white"), 글자색은 검정색("black")으로 설정됩니다.
- 만약 theme이 "dark"이면, 배경색은 검정색("black"), 글자색은 흰색("white")으로 설정됩니다.
- <div> 요소 안에는 "안녕하세요, 테마 변경이 가능한 웹사이트 입니다."라는 문장과 "테마 변경" 버튼이 포함되어 있습니다.
- "테마 변경" 버튼을 클릭하면, 해당 버튼에 등록된 onClick 이벤트 핸들러인 toggleTheme 함수가 호출됩니다.
- toggleTheme 함수는 현재의 theme 상태값을 확인하고, "light"이면 "dark"로, "dark"이면 "light"로 변경하여 setTheme을 통해 상태를 갱신합니다.
- setTheme 함수에 의해 theme 상태가 변경되면, DarkOrLight 컴포넌트가 다시 렌더링되어 ThemeContext.Provider가 새로운 theme 값과 toggleTheme 함수를 제공합니다.
- MainContent 컴포넌트는 useContext를 통해 새로운 theme 값과 toggleTheme 함수를 가져오고, 이에 따라 동적으로 변경된 스타일이 반영된 새로운 화면이 렌더링됩니다.
- 이렇게 사용자가 "테마 변경" 버튼을 클릭할 때마다, 테마에 따라 배경색과 글자색이 전환되어 보이는 효과를 가진 테마 변경이 가능한 웹사이트가 만들어집니다.