리액트에서 props는 다음과 같이 사용된다.
자식 컴포넌트에서 function을 아래와 같이 만들면,
function ChildComponent(props) {
const name = props.name;
const age = props.age;
return (
<p>
내 이름은 {name}이고 나이는 {age}살이야.
</p>
);
}
export default ChildComponent;
부모 컴포넌트에선 위 코드를 import한 뒤,
<ChildComponent name="부추" age={23} />
위와같이 props로 특성을 넣어준 뒤 부모 컴포넌트에서 렌더링하는 것이다.
porps는 기본적으로 정적이다. 한 번 부모 컴포넌트에서 자식에게 값이 전달되면 바뀌지 않는다. 이게 무슨 말이냐면, 만약 부모 컴포넌트에서 일어난 연산으로 인해 name(부추) 혹은 나이(23)이 바뀌어도 자식 컴포넌트에겐 전달되지 않는다는 말이다. 코드가 재실행되지 않는다!
... 그래서 나온 것이 State.
props와 반대로 동적인 값이다. import React from 'react'를 하면 거기에 useState()라는 함수가 들어있는 것을 확인할 수 있다. useState는 두 가지의 것(?)을 반환하는데, [state 값, state를 변경시키는 함수]가 그것이다.
예를 들어보자.
import React from "react";
function TimerComponent() {
const [time, setTime] = React.useState(0); // time값은 0으로 시작.
console.log("component updated...");
function updateTime() {
setTime(time + 1);
}
return (
<div>
<h3>{time}초</h3>
<button onClick={updateTime}>1씩 올려주쉐이~</button>
</div>
);
}
export default TimerComponent;
위 코드의 3번째 줄을 보아라. time과 setTime이다. setTime은 우리가 임의로 설정한 함수의 이름이며, time을 맘대로 변화시킬 수 있다. setTime 함수가 호출될 때마다 TimerComponent가 다시 실행되고, 저 컴포넌트 전체가 다시 렌더링되게 된다.
return의 버튼을 보면 이해가 조금 더 쉽다. onClick 이벤트가 발생할 때마다 updateTime 함수가 호출되는데, 이는 setTime에서 time이 1씩 증가하는 함수이다. 그렇다면 버튼이 눌린 만큼 <h3>{time}초</h3>에서 time값이 늘어난다는 얘기겠지?!
app.js에서 TimerComponent를 import하고 뚝딱거려보면 실제로 실행이 잘 된다는 것을 확인할 수 있을 것이다. (콘솔로그가 클릭할 때마다 찍히는건 덤)
그. 러. 나!
useState만 쓰면 무한루프에 걸릴 확률이 매우 높다. state를 변경시키는 함수가 호출되면 전체 컴포넌트가 다시 렌더링된다. 다시 렌더링되는 과정에서 또 state를 변경시키는 함수가 불리면 또 렌더링되고, 또 되고, 또 되고.. 환장의 무한루프에 빠져 페이지가 죽어버릴 수도 있다! 거기서 나오는 것이 useEffect이다.
기본적으로 useEffect는 useEffect(function, [모니터링 대상])의 형식을 취한다. 두번째 인자, 즉 [모니터링 대상]의 무언가 값이 바뀌면 첫번째 함수 인자가 실행되게 된다. 보통 function은 useState에 들어가는 function을 가지고있는 경우가 많다. (당연한 얘기지만..) 그래서 예를 보자면 다음과 같다.
function ComponentOnlyOnce(){
const [time, setTime] = React.useState(0);
React.useEffect(() => {
setTime(time+1); //state를 바꿔서 또 렌더링이 되더라도 setTime은 호출되지 않습니다.
console.log('컴포넌트가 화면에 처음 렌더링될 때 딱 한 번 실행됩니다.');
}, []);
}
useEffect 두번째 인자가 빈 배열이므로, 저 빈 배열은 영원히 업데이트되지 않으므로 setTime함수는 한 번만 실행된다.