마크업이나 스타일을 최대한 재사용할 수 있도록 아래 두가지 버튼을 예로 props를 사용해보자.

props?

props는 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법으로 어떠한 값을 컴포넌트에 전달 해줘야할 때 props를 사용한다.


props 사용해보기

아래 코드는 같은 스타일을 가진 버튼 두개를 만드는 코드이다.

style을 복붙하는 것 대신에 설정들을 넘겨줄 수 있는 버튼 컴포넌트를 만들어서 데이터를 전송해준 것이다.

function Btn({text}) {
	return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10
      }}>
      {text}
      </button>
    )
}

function App() {
	return (
      <div>
        <Btn text="Save Changes" />
        <Btn text="Continue" /> 
      </div>
    )
} 

const root = document.getElementById("root")
ReactDOM.render(<App />,  root)
  • <Btn text="Save Changes">
    text 데이터를 Btn 컴포넌트에 보낸다.
    그러나 function Btn() 컴포넌트에 인자가 없으면 text를 사용하지 않기때문에 argument(인자)를 사용하여 전달 받아야한다.

  • function Btn({text})
    text : App 컴포넌트의 prop text로부터 전달받은 properties

참고?
<img src=" "태그의 src="" 부분은 img태그에 정보를 전송하는데,
비슷한 방법으로 동일한 syntax를 사용하면서 새로운 데이터(정보)를 Btn 컴포넌트에 전송해준다.

참고2?
prop을 사용하는 다른 방식
function Btn(props) {
...
{props.text}
}

이렇게 사용할 수 있지만 위의 예제 코드처럼 property를 오브젝트로부터 꺼내는 방식을 선호한다고 한다.


true/false 전달하기

props는 오브젝트이기 때문에 우리가 App 컴포넌트의 Btn에서 보낸 모든 것들을 가질 수 있다.
따라서 인자를 하나만 가질 수 있는게 아니라 여러 데이터를 전달받아 사용할 수 있다.

function Btn({text, big}) {
	return (
    	<button style={{
        	...
            fontSize: big ? 18 : 16
        }}>
        {text}
        </button>
    )
}

function App() {
	return (
    	<div>
        	<Btn text="Save Changes" big={true}/>
            <Btn text="Continue" big={false}/> 
        </div>
    )
} 

  • <Btn text="Save Changes" big={true}/>
    props는 string 뿐만 아니라 true/false 및 함수도 함께 보낼 수 있다.

  • function Btn({text, big})
    이처럼 App에서 전달받은 prop인 big을 Btn 컴포넌트에서 두번째 인자로 사용할 수 있는데 넘어온 데이터의 true/false 여부를 통하여 fontSize를 달리 할 수도있다.


React memo

우선 React memo의 필요성에 대해 알아보기 위해 state를 활용하여 컴포넌트 상태가 바뀌는 예시를 들어보자

함수 전달하기

function Btn({text, onClick}) {
	console.log(text, "was rendered"
	return (
		<button 
    		onClick = {onClick}
        	...
    	}}>
    	{text}
    	</button>
    )
}
        
function App() {
	const [value, setValue] = React.useState("Save Changes")
    const changeValue = () => setValue("Revert Changes")
    return (
    	<div>
        	<Btn text={value} onClick={changeValue} />
            <Btn text="Continue" /> 
        </div>
    )
} 

  • const [value, setValue] = React.useState("Save Changes")
    const changeValue = () => setValue("Revert Changes")

    Save Changes -> Revert Changes로 변경되는 state 만들기

  • <Btn text={value} onClick={changeValue} />
    이벤트가 발생할 수 있도록 함수 데이터 전달

    중요!!
    여기서 전달하는 onClick은 실제 이벤트리스너가 아니라 Btn 컴포넌트로 전달하는 prop이다. text 처럼 그냥 이름이기 때문에 Btn 컴포넌트에서 이름을 가져와서 적용시켜주어야 함에 유의하자.





memo의 필요성

-처음 페이지 렌더했을때 로그

-Save Changes 버튼 클릭했을때 로그

컴포넌트는 상태가 바뀌면 re-render를 하는데 이로 인해서 Save Changes 버튼을 눌럿을때 해당 버튼만 렌더되는 것이 아닌 Continue 버튼도 다시 렌더되는 것을 볼 수 있다.

그러나 변경된 사항이 없는 Continue 버튼의 경우 렌더를 다시할 필요가 없기때문에 React memo를 이용하여 개선할 수 있다.

memo 사용하기

React memo는 컴포넌트가 다시 그려지는 것을 윈치않을 경우에 props가 변경되지 않는 한에서 사용할 수 있다.

state가 변경되면 Changes 버튼도 변경되어야하는데 Continue 버튼의 경우 onClick props가 아니기때문에 re-render를 방지하기 위해 React에 해당 버튼의 re-render를 멈춰달라고 말할 수 있다.

function Btn({text, onClick}) {
	...
}

const MemorizedBtn = React.memo(Btn)

function App() {
	const [value, setValue] = React.useState("Save Changes")
    const changeValue = () => setValue("Revert Changes")
    return (
    	<div>
        	<MemorizedBtn text={value} onClick={changeValue} />
            <MemorizedBtn text="Continue" /> 
        </div>
    )
} 
  • const MemorizedBtn = React.memo(Btn)
    function Btn() 으로 컴포넌트를 생성해주고,
    MemorizeBtn은 memorized 버전의 Btn이 된다.

  • <MemorizedBtn text={value} onClick={changeValue} />
    <MemorizedBtn text="Continue" /
    >
    App 컴포넌트의 Btn -> MemorizedBtn로 교체하여 Continue 버튼의 re-render를 방지할 수 있다.



-처음 페이지 렌더했을때 로그

-Save Changes 버튼 클릭했을때 로그


이처럼 memo를 사용하면 필요한 부분만 렌더되어 Continue 버튼이 re-render 되지 않는 것을 확인할 수 있다.

부모의 state가 변경되면 모든 자식은 re-render되기 때문에 어플리케이션이 느려지는 원인이 될 수 있다. 따라서 memo를 적절히 사용하면 이를 방지할 수 있는 좋은 방법이 된다.




Props Type

유저가 prop으로 데이터를 전달할때 Syntax error가 아닌 실수가 발생 할 수 있다.

예를 들어

<Btn text="Save Changes" fontSize={18} />
<Btn text="{14}" fontSize="Continue" />

두번째 버튼에서 우리는 text -> string, fontSize -> number 타입이 나오길 바라지만 React.js는 구분할 줄 모른다.

props type은 이럴 경우에 사용하여 prop들이 무슨 type인지 알려줄 수 있다.

<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
  
...
  
Btn.propType = {
  	text: PropTypes.string.isRequired
  	fontSize: PropTypes.number
}

위처럼 propType을 사용하면 props의 타입이 어떤것이고 어떤 모양이어야하는지 정의할 수 있기 때문에 벗어날 경우 콘솔창에서 경고로그를 확인 할 수 있다.

profile
Node 백엔드 개발자 / 데브옵스 취준생

0개의 댓글

Powered by GraphCDN, the GraphQL CDN