-
[React] ์ด๋ฒคํธ ์ฒ๋ฆฌ & Controlled Component & React ๋ฐ์ดํฐ ํ๋ฆcodeStates front-end/React 2023. 1. 26. 14:08๋ฐ์ํ
๐๋ฆฌ์กํธ ๊ฐ๋
๐์ด๋ฒคํธ ์ฒ๋ฆฌ( Event handling )
React ์์ ์ด๋ฒคํธ๋ ์๋ฌธ์ ๋์ ์นด๋ฉ ์ผ์ด์ค๋ฅผ ์ฌ์ฉ
JSX๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ด ์๋ ํจ์๋ก ์ด๋ฒคํธ ์ฒ๋ฆฌ ํจ์๋ฅผ ์ ๋ฌ
<button onclick="handleEvent()">Event</button> // html <button onClick={handleEvent}>Event</button> // react
๐ onChange
ํผ(Form) ์๋ฆฌ๋จผํธ (<input><textarea><select>) ๋ ์ ๋ ฅ๊ฐ์ ์ ์ดํ๋ ๋ฐ ์ฌ์ฉ
๋ณ๊ฒฝ๋ ์ ์๋ ์ ๋ ฅ๊ฐ -> ์ปดํฌ๋ํธ์ state๋ก ๊ด๋ฆฌ
function NameForm() { const [name, setName] = useState(""); const handleChange = (e) => { setName(e.target.value); // onChange ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด e.target.value๋ฅผ ํตํด input ๊ฐ์ ์ฝ์ด์ด } return ( <div> {/* inputํ๊ทธ ์์ value์ onChange(ํ ์คํธ๊ฐ ๋ฐ๋ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ)๋ฅผ ๋ฃ์ด์ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด handleChange ํจ์๊ฐ ์๋ ์๋ก์ด state๋ก ๊ฐฑ์ */} <input type="text" value={name} onChange={handleChange}></input> <h1>{name}</h1> </div> ) };
onChange ์ค์ต
import React, { useState } from "react"; import "./styles.css"; function SelectExample() { const [choice, setChoice] = useState("apple"); const fruits = ["apple", "orange", "pineapple", "strawberry", "grape"]; const options = fruits.map((fruit) => { return <option value={fruit}>{fruit}</option>; }); console.log(choice); const handleFruit = (event) => { setChoice(event.target.value); };
์คํ๊ฒฐ๊ณผ
์ต์ ์ ์ ํํ ๋๋ง๋ค text๊ฐ ๋ณ๊ฒฝ๋จ์ด ํ์ธ ๊ฐ๋ฅํ๋ค
๐ onClick
์ฌ์ฉ์๊ฐ ํด๋ฆญ์ด๋ผ๋ ํ๋์ ํ์์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ
function NameForm() { const [name, setName] = useState(""); const handleChange = (e) => { setName(e.target.value); } return ( <div> {/* input tag ์ ์ ๋ ฅํ ์ด๋ฆ์ด alert์ ํตํด ์๋ฆผ ์ฐฝ์ด ํ์ ๋๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐ */} <input type="text" value={name} onChange={handleChange}></input> <button onClick={alert(name)}>Button</button> <h1>{name}</h1> </div> ); };
onClick ์ด๋ฒคํธ์ ํจ์๋ฅผ ์ ๋ฌํ ๋๋ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ์๋๋ผ ์๋์ ๊ฐ์ด ๋ฆฌํด๋ฌธ ์์์ ํจ์๋ฅผ ์ ์ํ๊ฑฐ๋
๋ฆฌํด๋ฌธ ์ธ๋ถ์์ ํจ์๋ฅผ ์ ์ ํ ์ด๋ฒคํธ์ ํจ์ ์์ฒด๋ฅผ ์ ๋ฌ
// ํจ์ ์ ์ํ๊ธฐ return ( <div> ... <button onClick={() => alert(name)}>Button</button> ... </div> ); }; // ํจ์ ์์ฒด๋ฅผ ์ ๋ฌํ๊ธฐ const handleClick = () => { alert(name); }; return ( <div> ... <button onClick={handleClick}>Button</button> ... </div> ); };
onClick ์ค์ต
import "./styles.css"; import React, { useState } from "react"; function NameForm() { const [name, setName] = useState(""); const handleChange = (e) => { setName(e.target.value); }; const handleClick = () => { alert(name); }; return ( <div className="App"> <h1>Event handler practice</h1> <input type="text" value={name} onChange={handleChange}></input> <button onClick={handleClick}>Button</button> // ํจ์๋ฅผ ํธ์ถ(์ด ๋ฐฉ๋ฒ์ ๋ ์ ํธ) <button onClick={() => alert(name)}>Button</button> // ํจ์๋ฅผ ์ ์ธ ๋ฐ ํธ์ถ <h3>{name}</h3> </div> ); } export default NameForm;
์คํ ๊ฒฐ๊ณผ ๋๊ฐ์ง ๋ฒํผ ๋ชจ๋ alert์ด ๋จ๋ ๊ฒ์ด ํ์ธ ๊ฐ๋ฅํ๋ค
popup ์ค์ต
import React, { useState } from "react"; import "./styles.css"; function App() { const [showPopup, setShowPopup] = useState(false); const togglePopup = (e) => { // Pop up ์ open/close ์ํ์ ๋ฐ๋ผ // ํ์ฌ state ๊ฐ ์ ๋ฐ์ดํธ ๋๋๋ก ํจ์๋ฅผ ์์ฑํ์ธ์. if (showPopup === false) { setShowPopup(true); } else setShowPopup(false); }; return ( <div className="App"> <h1>Fix me to open Pop Up</h1> {/* ๋ฒํผ์ ํด๋ฆญํ์ ๋ Pop up ์ open/close ๊ฐ ์๋ํ๋๋ก button tag๋ฅผ ์์ฑํ์ธ์. */} <button className="open" onClick={togglePopup}> Open me </button> {showPopup ? ( <div className="popup"> <div className="popup_inner"> <h2>Success!</h2> <button className="close" onClick={togglePopup}> Close me </button> </div> </div> ) : null} </div> ); } export default App;
์คํ๊ฒฐ๊ณผ
๐Controlled Component
๋ฆฌ์กํธ๊ฐ state์ ํต์ ํ ์ ์๋ ์ปดํฌ๋ํธ๋ฅผ ์ปจํธ๋กค ์ปดํฌ๋ํธ๋ผ๊ณ ํ๋ค.
controlled component ์ค์ต
import "./styles.css"; import React, { useState } from "react"; export default function App() { const [username, setUsername] = useState(""); const [msg, setMsg] = useState(""); return ( <div className="App"> <div>{username}</div> <input type="text" value={username} onChange={(event) => setUsername(event.target.value)} // ์ปจํธ๋กค ์ปดํฌ๋ํธ placeholder="์ฌ๊ธฐ๋ ์ธํ์ ๋๋ค." className="tweetForm__input--username" ></input> <div>{msg}</div> {/* TODO : ์ input๊ณผ ๊ฐ์ด ์ ๋ ฅ์ ๋ฐ๋ผ์ msg state๊ฐ ๋ณํ ์ ์๊ฒ ์๋ textarea๋ฅผ ๋ณ๊ฒฝํ์ธ์. */} <textarea placeholder="์ฌ๊ธฐ๋ ํ ์คํธ ์์ญ์ ๋๋ค." className="tweetForm__input--message" onChange={(event) => setMsg(event.target.value)} value={""} ></textarea> </div> ); }
์คํ ๊ฒฐ๊ณผ
๐ React ๋ฐ์ดํฐ ํ๋ฆ
ํ์ด์ง ๋จ์ x -> ์ปดํฌ๋ํธ ๋จ์ o
์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ ๋ค์ ํ์ด์ง๋ฅผ ์กฐ๋ฆฝ
์ปดํฌ๋ํธ๋ ์ํฅ์(bottom-up)์ผ๋ก ์ ์ -> ํ ์คํธ๊ฐ ์ฝ๊ณ ํ์ฅ์ฑ์ด ์ข๋ค
ํธ๋ฆฌ๊ตฌ์กฐ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ ๋ค
๋ฐ์ดํฐ๋ฅผ ์ด๋์ ๋์ง ๊ฒฐ์
์ปดํฌ๋ํธ๋ ์ปดํฌ๋ํธ ๋ฐ๊นฅ์์ props๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ง์น ์ธ์ ํน์ ์์ฑ ์ฒ๋ผ
์ ๋ฌ๋ฐ์ ์ ์๋ค.
๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ฃผ์ฒด -> ๋ถ๋ชจ ์ปดํฌ๋ํธ : ๋ฐ์ดํฐ ํ๋ฆ์ด ํํฅ์(top-down)์์ ์๋ฏธ
๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ(one-way data flow)
์ปดํฌ๋ํธ๋ props๋ฅผ ํตํด ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๊ฐ ์ด๋์ ์๋์ง ์ ์ ์์
์ํ๋ ์ต์ํํ๋ ๊ฒ์ด ์ข๋ค(๋ณต์ก์ฑ ๋๋ฌธ)
- ๋ถ๋ชจ๋ก๋ถํฐ props๋ฅผ ํตํด ์ ๋ฌ๋ฉ๋๊น? ๊ทธ๋ฌ๋ฉด ํ์คํ state๊ฐ ์๋๋๋ค.
- ์๊ฐ์ด ์ง๋๋ ๋ณํ์ง ์๋์? ๊ทธ๋ฌ๋ฉด ํ์คํ state๊ฐ ์๋๋๋ค.
- ์ปดํฌ๋ํธ ์์ ๋ค๋ฅธ state๋ props๋ฅผ ๊ฐ์ง๊ณ ๊ณ์ฐ ๊ฐ๋ฅํ๊ฐ์? ๊ทธ๋ ๋ค๋ฉด state๊ฐ ์๋๋๋ค.
์ํ๋ฅผ ์ด๋์ ์์น์์ผ์ผ ํ๋์ง ์ดํด๋ด์ผ ํ๋ค
A component , B component -> parent component ๋ผ๋ฉด, parent ์ ์ํ๋ฅผ ์์น
๋ฐ์ํ'codeStates front-end > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] ๋ฐ์ดํฐ ํ๋ฆ (0) 2023.02.02 [React] ์ค์ต - React Twittler State & Props (0) 2023.01.30 [React] State & Props & ๋ ๋๋ง ์ ์ (0) 2023.01.25 [React] ์ค์ต - react twittler SPA (0) 2023.01.25 [React] SPA, Router (0) 2023.01.25