해당 내용은 노마드 코더의 강의 및 React 공식 문서, 공식문서 번역을 참고하여 작성한 글입니다.
올바르지 않은 내용이 있다면 의견 남겨주세요. 언제든지 환영입니다.
1. Props
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
// prop: 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법
// 버튼을 N개 만든다고 해보자, 이때 버튼의 스타일이 동일하고 글자만 다르다면, TEXT만 바꿔서 만들 수 있도록 수정할 수 있어야 한다.
function Button({berry, onClick}) {
console.log(`${berry} was rendered`);
// button컴포넌트에 던진 berry라는 key 가져오기
// console.log(props.berry);
// return(
// <button>{props.berry}</button>
// )
// shortcut: Button({berry})를 통해 Button(props)의 props.berry 대신 편하게 쓴다
// props로 받아온 onClick을 return을 통해 실제 이벤트 리스터 등록했다.
return (
<button onClick={onClick}>{berry}</button>
)
}
function App() {
const [value, setValue] = React.useState("burabong!");
const handleClick = () => {
setValue("cute burabong🍊");
}
return (
<>
<Button berry={value} onClick={handleClick}/>
<Button berry="banana"/>
</>
)
//<Button berry="{value}" onClick={handleClick}/> 의 onClick은 이벤트 리스너가 아니다. berry와 마찬가지로 props다.
}
ReactDOM.render(<App/>, root);
</script>
</html>
부모에서 자식으로 넘기는 props
- 처음 실행 시 <button> 컴포넌트를 통해 렌더링
- 버튼 클릭 시 <button> 재렌더링
협업 진행 시 해당 props 데이터는 문자만 와야하고, 필수로 넘겨주어야 할 부분들이 존재할 수 있다. 이때, PropsTypes를 이용하여 해당 key의 타입이 어떤 건지 정의해주면 개발자 도구에서 오류로 안내해준다.
https://classic.yarnpkg.com/en/package/prop-types
prop-types
Runtime type checking for React props and similar objects.
classic.yarnpkg.com
만일 사용하고 싶다면, react 설치 후 yarn add prop-types 명령어로 설치하면 사용 가능하다.
2. useEffect
import logo from './logo.svg';
import './App.css';
import Button from './Button';
import { useState, useEffect } from 'react';
function App() {
const [counter , setCounter] = useState(0);
const [keyword, setKeyword] = useState('');
const handleClick = () => (setCounter((prev) => prev + 1));
const handleChange = (e) => {
setKeyword(e.target.value);
}
// 내가 state를 변경할 때마다 모든 컴포넌트가 재 render 됨. 하지만 일부 컴포넌트는 재 렌더링 되길 원하지 않음
// useEffect 첫번쨰 인자 : 우리가 한번만 실행시키고 싶은 코드,
// 우리가 코드가 딱 한번만 실행할 수 있도록 보호하는 useEffect, state가 변화하든 무슨일이 있어도 1번
useEffect(() => {
console.log(`call the api`);
}, []);
useEffect(() => {
// 3.keyword가 빈값이 아니고 5단어가 되면 해당 로그 찍어줘
if(keyword !== '' && keyword.length > 4) console.log(`useEffect keyword is ${keyword}`);
}, [keyword]) // 2. keyword가 변경될 때만 해당 log 찍어줘, 그럼 [] 문자열 쓰면 판단할게 없으니 단 한번만 나오겠지
useEffect(() => {
console.log(`i run when "counter" change`);
}, [counter]);
useEffect(() => {
console.log(`i run when "keyword & counter" change`);
}, [keyword, counter]); // 4. keyword || counter 이다.
// 1. 입력할 때마다 재실행되고 있음, 낭비!
//console.log(`keyword is ${keyword}`);
return (
<>
<input type="text" placeholder='search' value={keyword} onChange={handleChange}/>
<div>Click me {counter}</div>
<button onClick={handleClick}> Click me!</button>
</>
);
}
export default App;
App.js
- useEffect(effect: React.EffectCallback, deps?: React.DependencyList)
- effect: useEffect의 첫번째 인자. 정리 함수를 반환할 수 있는 명령형 함수. 해당 함수를 통해 우리는 딱 한번만 실행시키고 싶은 내용을 작성한다.
- dependencyList : useEffect의 두번째 인자. [ ] 적힌 값이 변경되는 경우에만 effect 함수가 실행된다. 아무것도 안적으면 최초 1번, [a, b] 둘다 적으면 a or b와 같다. a만 변경되거나 b만 변경되었을때도 해당 effect 함수가 실행된다.
import logo from './logo.svg';
import './App.css';
import Button from './Button';
import { useState, useEffect } from 'react';
function Hello() {
// useEffect의 생성, 해지 되었을 때 이런식으로 동작함을 파악할수 있다.
useEffect(() => {
console.log('created :)');
return () => console.log('destoryed :/');
}, []);
return(<h1>Hello</h1>)
}
function App() {
const [showing, setShowing] = useState(false);
const handleClick = () => (setShowing((prev) => !prev));
return (
<>
{showing ? <Hello/> : null}
<button onClick={handleClick}>{showing ? 'Hide' : 'Show'}</button>
</>
);
}
export default App;
useEffect 생성, 해지