해당 내용은 노마드 코더의 강의 및 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

props를 통한 렌더링 문제

  1. 처음 실행 시 <button> 컴포넌트를 통해 렌더링
  2. 버튼 클릭 시 <button> 재렌더링

props 타입 정리

 

협업 진행 시 해당 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 생성, 해지

+ Recent posts