2022년 11월 11일
React
카테고리 : React
조회 : 861|2분 읽기

React State와 Props

React하면 state

state(상태)는 React의 꽃이라 볼 수 있다.
상태는 일반 JS 객체이며 렌더링 결과물에 영향을 주는 정보를 가지고 있다.
상태가 변경된다면 자동으로 rerendering이 되는데 이것을 통해 앱의 데이터를 동적으로 다룰 수 있다.
따라서 우리는 상태를 관리하는 것에 예민해야 하며 잘 못 작성된 상태로 많은 rerendering이 발생한다면 앱의 성능을 저하시킬 수 있다.
그래서 상태를 관리하기 위한 라이브러리들도 존재한다.
이 라이브러리들은 컴포넌트들간의 상태를 공유 및 관리가 가능하게 만들어 준다.

State

상태란

component 안에서 변경(관리)이 가능한 데이터

🔔 UI를 새로고침해 주는 코드가 존재하지 않기 때문에 버튼을 클릭해도 페이지가 rerendering 되기 전까진 바뀐 count는 업데이트가 안된다.
javascript
1import { useState } from 'react';
2 
3function Example() {
4    const [count, setCount] = useState(0);
5    return (
6        <div>
7            <p>버튼을 {count}번 눌렀습니다.</p>
8            <button onClick={() => setCount(count + 1)}>클릭</button>
9        </div>
10    );
11}



🔔 setState
상태 값을 바꾸는데 setState를 사용한다. 이 훅은 상태값이 바뀌면 rerendering을 해야하는 타이밍이라는 걸 알게 해준다.
만약 사용하지 않고 그냥 state를 바꾼다면 rerendering이 일어나지 않아 바뀐 데이터가 포함된 UI가 표현되지 않을 것이다.
setState는 이벤트 핸들러 내에서 비동기적으로 작동한다. 만약 동기적으로 작동하게 만들고 싶다면 useEffect를 사용할 수 있다.
setState를 사용하는데는 두가지 방법이 있다.
javascript
1const [count, setCount] = useState(0)
2
3// 1. 변경할 값 넣기
4setCount(count+1)
5
6// 2. 함수를 넣기
7setCount(prev=> prev+1)
1번은 상태 값이 어디서 어떤식으로 변경이 된 후 여기 있는지 모를 경우가 있는데 그 경우 의도하는 상태 값이 아닐 수 도 있다.
만약 여기 저기 상태의 set을 많이 하는 경우 이 방법은 지양해야한다.
2번은 함수를 넣어 이전 상태값을 기준으로 변경하기 때문에 좀 더 안전한 방법이다.



🔔 분을 시간으로 시간을 분으로 바꾸는 기능을 가진 App
🔧 순서
  1. onChange는 변화를 감지하고 value는 값을 받는다.
  2. flipped의 초기값은 false로 설정했고 함수가 실행된다면 flipped 초기값의 반대인 !flipped로 된다. setFlipped((current)=>!current);
  3. inverted가 true일때 disabled가 활성화 된다.
javascript
1function App() {
2  const [amount,setAmount] = useState();
3  const [inverted,setInverted]= useState(false);
4  const onChange = (e) =>{
5    // 이벤트의 값을 minutes에 넣는다.
6    setAmount(e.target.value);
7  }
8const reset = () => setAmount(0);
9const onFlip = () => setFlipped((current)=>!current);
10  
11 return(
12   <div>
13   	<h3>Time Converter</h3>
14    	<label htmlFor="min">Minutes</label>
15	<input value={inverted ? amount*60 : amount} id="min" placeholder="Min" type="number" onChange={onChange}disabled={inverted}/>
16   
17   <h4>시간(hr)으로 바꾸기 원하는 (min)?{minutes}</h4>
18
19   	<label htmlFor="hr">Hours</label>
20   	<input id="hr" placeholder="Hour" type="number" value={inverted ? amount : Math.round(amount / 60)} disabled={!inverted}/>
21	<button onClick={reset}>Reset</button>
22	<button onClick={onFlip}>{inverted ? "Turn back" : "Invert"}</button>
23</div>
24);
25};


Props

Props란

컴포넌트를 분리시킬때(부모 > 자식으로)나 중복되는 컴포넌트를 통해 원하는 인자(데이터)들을 주고받을 경우가 필요할때 이용한다.
🔔 Btn컴포넌트를 이용할때 Btn({text:"Save"})로 인자가 들어있는 함수를 사용하는 것과 같다.
props안에 인자 text와 같은 것은 임의로 설정 가능하다.
ex)
javascript
1  
2function Btn(props){
3  	console.log(props); // {text: "Save",x:false}, {text:"Continue",y:7}
4	return <button onClick={props.changeValue}>{props.text}</button>;
5}
6const MemorizedBtn = React.memo(Btn);
7function App(){
8  const [value,setValue] = useState("Save");
9  const changeValue = () => setValue("Changed");
10return( 
11  	<div>	
12    	<MemorizedBtn text="Save" x={false} changeValue={changeValue}/>
13  		<MemorizedBtn text="Continue" y=7/>
14    </div>;
15  )
16}
text="Save"와 banana="Save"는 컴포넌트에서 받는 값만 서로 같다면 역할을 할 수 있다.
함수도 props를 통해 내릴 수 있다. 이 때 내릴 함수는 부모에서만 관리가 가능하다.

🔔 구조분해할당을 사용하면 더 쉽게 컴포넌트에 js값을 할당 할 수 있다.
javascript
1function Btn({text}){
2	return <div>{text}</div>;
3}
🔔 const MemorizedBtn = React.memo(Btn);
부모 컴포넌트 state변경이 존재한다면 모든 자식들은 rerender된다.
하지만 React.memo의 기능은 state가 변경된 자식만 rerender된다.

Prop Types

PropTypes는 props의 형태를 실수하지 않게 도와준다.
jsDoc과 같은 역할을 한다.
javascript
1  Btn.propTypes  = {
2	  text : PropTypes.string,  
3  };


State와 Props 차이점

State는 자기 자신 컴포넌트 내에서 바꿀 수 있는 값 Props는 부모에서 자식에게 내리는 값 컴포넌트는 이 값을 변경할 수 없다.
부모로부터 받은 props 와 state 초기값은 모두 Component 내부에 정의된 기본값보다 우선이다.
공통점
  1. 상위 구성 요소에서 초기값을 가져올 수 있다.
  2. 컴포넌트 내에서 기본값을 설정할 수 있다.
  3. 자식 컴포넌트의 초기값을 설정할 수 있다.
차이점
  1. 상위 컴포넌트로 변경이 가능한가? state : no <> props : yes
  2. 컴포넌트 내부에서 변경이 가능한가? state : yes <> props : no
  3. 자식 구성 요소에서 변경이 가능한가? state : no <> props : yes