Unit6 - [React] React State & Props
State : 내부에서 변화하는 값 ,컴포넌트의 사용중 내부에서 변할수 있는 값
ex)나이,사는 곳 ,취업 여부 , 결혼/연애 여부
Props : 외부로부터 전달받은 값
ex) 이름 , 성별
특징
- 컴포넌트의 속성
- 부모 컴포넌트(상위 컴포넌트)로부터 전달 받은 값
->React 컴포넌트는 JavaScript 함수와 클래스로, props를 함수의 전달인자(arguments)처럼 전달받아 이를 기반으로 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환
- 객체 형태
- 읽기 전용(외부로부터 전달받아 변하지 않는 값)
사용하는 방법
- 하위 컴포넌트에 전달하고자 하는 값(data)과 속성을 정의
- props를 이용하여 정의된 값과 속성을 전달
- 전달받은 props를 렌더링
unction Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child text={"Hello Child"} /> //<Parent>컴포넌트안에 <Child> 컴포넌트를 작성한다.
// text속성을 선언하고 이 속성에 문자열을 넣는다.
// 문자열을 props로 전달한다.
<Child />
<Child text={"Hello props"}
<Child />
</div>
);
}
function Child(props) { //props를 전달받고
console.log("props : ", props);
return (
<div className="child">
<p>{props.text}</p> //이 props를 렌더링한다.
</div>
);
}
export default Parent;
또 다른 방법
import "./styles.css";
const App = () => {
const itemOne = "React를";
const itemTwo = "배우고 있습니다.";
return (
<div className="App">
<Learn>{itemOne} {itemTwo}</Learn>
</div>
);
};
const Learn = (props) => {
return (
<div className="Learn">
<p>{props.children}</p>
</div>
);
};
export default App;
퀴즈
Props는 클래스 컴포넌트와 함수형 컴포넌트에서 사용할수 있다.
ES6 class 문법으로도 컴포넌트를 만들 수 있고, 이를 클래스 컴포넌트
함수 문법을 사용하여 만든 컴포넌트를 말 그대로 함수 컴포넌트
Hook이 나오기 전에는 state는 클래스 컴포넌트에만 다룰 수 있었으나
Hook이 나오면서 함수 컴포넌트도 state를 다룰 수 있다.
props는 여러 개 지정
state는 하위 컴포넌트에서도 존재
State hook, useState
React에서는 state 를 다루는 방법
useState라는 함수 제공
import { useState } from "react";
useState를 컴포넌트안에서 호출-> state 변소를 선언 ( react에 의해 함수가 끝나도 사라지지 않음)
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false); // 1번
//const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
->
const stateHookArray = useState(false); // 2번 (useState의 인자를 넘겨주는 것은 state의 초기값)
const isChecked = stateHookArray[0]; (현재 state변수)
const setIsChecked = stateHookArray[1]; (이 변수를 갱신할수 있는 함수)
}
useState : statehook
state 갱신
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);
const handleChecked = (event) => {
setIsChecked(event.target.checked); //state 갱신 -> setIsChecked함수 호출
};
return (
<div className="App">
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>
);
}
useState hook을 사용하여 checkbox의 체크 상태를 관리
. isChecked라는 state를 선언하고, 처음에는 false로 설정.
handleChecked 함수는 checkbox의 상태가 변경될 때 호출
. 이 함수는 checkbox의 상태를 event.target.checked로부터 얻어온다.
그리고 setIsChecked 함수를 호출하여 state를 갱신
마지막으로, checkbox 컴포넌트와 체크 상태에 따라 "Checked!!" 또는 "Unchecked"라는 문구가 보이는 텍스트 컴포넌트를 렌더링
React state는 상태 변경 함수 호출로 변경
정리 : 시용자 체크박스 값 변경하면 onChange 이벤트가 이벤트 핸드러 함수인 handleChecked를 호출하고
이 함수가 setIsChecked를 호출하게 된다.setIsChecked가 호출되면 호출된 결과에 따라 isChecked변수가 갱신
React는 새로운 isChecked 변수를 CheckboxExample 컴포넌트에 넘겨 해당 컴포넌트를 다시 렌더링
이벤트처리
카멜 케이스(camelCase) 를 사용
JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수(이벤트 핸들러; Event handler)를 전달
<button onClick={handleEvent}>Event</button>
변경될 수 있는 입력값을 일반적으로 컴포넌트의 state 로 관리하고 업데이트
function NameForm() { //4. NameForm컴포넌트에 넘겨 해당 컴포넌트에 렌더링
const [name, setName] = useState("");
const handleChange = (e) => { //2. 호출된 함수는 setName을 호출
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input> //1. 값 변경하면 handleChange함수호출
<h1>{name}</h1> //3. 호출된 결과에 따라 name변수 갱신
</div>
)
};
정리 사용자 텍스트 값 변경하면 onChange 이벤트가 이벤트 핸드러 함수인 handleChecked를 호출하고
이 함수가 setName를 호출하게 된다.setIName가 호출되면 호출된 결과에 따라 name변수가 갱신
React는 새로운 name 변수를 NameForm 컴포넌트에 넘겨 해당 컴포넌트를 다시 렌더링
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">
<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;
<select>
import React, { useState } from "react";
import "./styles.css";
function SelectExample() {
const [choice, setChoice] = useState("apple");
const fruits = ["apple", "banana", "melon", "strawberry", "Kiwi"];
const options = fruits.map((fruit) => {
return <option value={fruit}>{fruit}</option>;
});
console.log(choice);
const handleFruit = (event) => {
setChoice(event.target.value);
};
return (
<div className="App">
<select onChange={handleFruit}>{options}</select>
<h3>{choice}</h3>
</div>
);
}
export default SelectExample;
Pop up
import React, { useState } from "react";
import "./styles.css";
function App() {
const [showPopup, setShowPopup] = useState(false);
const togglePopup = (event) => {
setShowPopup(!showPopup); //true와 false 사이를 전환하는 것
//setShowPopup 함수를 사용하여 새 값으로 상태를 업데이트
};
return (
<div className="App">
<button className="open" onClick={togglePopup}>
Open
</button>
{showPopup ? (
<div className="popup">
<div className="popup_inner">
<button className="close" onClick={togglePopup}>
Close
</button>
</div>
</div>
) : null}
</div>
);
}
export default App;
Controlled Component
React에서는 상태에 해당하는 데이터를 state로 따로 관리하고 싶어한다.
React가 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="username"
className="tweetForm__input--username"
></input>
<div>{msg}</div>
<textarea
placeholder="text"
className="tweetForm__input--message"
onChange={(event) => {setMsg(event.target.value);}}
value={msg}
></textarea>
</div>
);
}
React 데이터 흐름
React 개발 방식 : 컴포넌트 단위로 시작
하나의 컴포넌트는 한가지 일만 한다. (단일 책임 원칙)
상향식으로 앱 만들기
테스트가 쉽고 , 확장성이 좋다.
트리구조 작성
데이터 흐름은 하향식 ,단방향 데이터 흐름
컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달
테이터는 위에서 아래로 흐른다.
데이터를 전달하는 주체는 부모 컴포넌트가 된다.
상태 위치 정하기
상태가 특정 컴포넌트에서만 유의미 -> 특정 컴포넌트에만 두면 된다.
하나의 상태를 기반으로 두 컴포넌트가 영향 -> 공통 소유 컴포넌트를 찾아 그곳에 상태를 위치
퀴즈
props는 하위 컴포넌트로 내려갈 수 있지만, 상향식으로 전달x
React에서 useState hook을 이용해 click-to-edit UI를 구현하는 방법
import { useState } from 'react';
function MyComponent() {
const [editing, setEditing] = useState(false);
const [text, setText] = useState("Initial text");
function handleClick() {
setEditing(true);
}
function handleChange(e) {
setText(e.target.value);
}
function handleBlur() {
setEditing(false);
}
return (
<div>
{editing ? (
<input
type="text"
value={text}
onChange={handleChange}
onBlur={handleBlur}
/>
) : (
<span onClick={handleClick}>{text}</span>
)}
</div>
);
}
- onClick은 HTML 요소에서 클릭 이벤트가 발생할 때 실행되는 이벤트 리스너, handclick함수를 실행시켜 input요소를 보여준다.
- onChange : 입력 값이 변경될 때마다 실행되는 이벤트 리스너, handleChange 함수를 실행하여 text state를 업데이트한다.
- onBlur : 요소가 포커스를 잃었을 때 실행되는 이벤트 리스너, handleBlur 함수를 실행시켜 input요소를 숨긴다.
local state 적용
"Local state"란 특정 컴포넌트나 모듈의 내부 상태를 의미
이러한 상태는 해당 컴포넌트나 모듈 안에서만 유효하며, 다른 컴포넌트나 모듈에는 영향을 주지 않는다. 이 상태를 관리하는 것을 "local state 적용"이라고 한다.
React에 존재하는 다양한 Hook들
React에는 다음과 같은 다양한 Hook들이 존합니다.
- useState: 컴포넌트의 state를 관리할 때 사용하는 Hook
- useEffect: 컴포넌트가 렌더링될 때 특정 작업을 수행할 때 사용하는 Hook
- useContext: Context API를 사용할 때 사용하는 Hook
- useReducer: 리듀서 함수를 사용해 state를 관리할 때 사용하는 Hook
- useCallback: 함수 컴포넌트에서 같은 함수를 여러 번 재사용할 때 사용하는 Hook
- useMemo: 함수 컴포넌트에서 연산 결과를 재사용할 때 사용하는 Hook
- useRef: DOM 요소를 참조하거나, 클래스 컴포넌트와 비슷한 기능을 구현할 때 사용하는 Hook
이들 Hook들을 사용하면 컴포넌트를 구성하는데 필요한 다양한 기능들을 쉽게 구현 가능
이런게 다양한 hoot기능들이 있는지 몰랐다. 예제를 찾아보면서 공부해야겠다..
난 한참 멀었구나^^..
event.target => 이벤트가 발생한 요소