버튼의 이름만을 제외한 색이나 패딩같은 스타일은 같은 버튼을 여러개 만들고 싶다면 CSS에 작성하여 같은 스타일을 가져올 수도 있고
function SaveBtn() {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10
}}>Save Changes</button>
);
}
function ConfirmBtn() {
return (
<button>Confirm</button>
);
}
위의 JSX의 SaveBtn 안에 스타일에 적은 값들을 ConfrimBtn에도 똑같이 옮겨 담을 수도 있을 것이다. 하지만 많은 속성이 겹치는 버튼에서 몇가지만 다르게 하기 위하여 매개변수로 값을 전달할 수 있으면 재사용성이 훨씬 좋아질 것이고, 이를 위하여 사용하는 것이 props
이다.
function App() {
return (
<div>
<Btn banana="Save Changes" x={false} />
<Btn banana="Continue" y={7} />
</div>
);
}
먼저 최종 Btn 컴포넌트에서 banana
라고 하는 임의의 값을 전달해 준다고 하자, 내가 만든 banana, x는 오브젝트로 묶여 function Btn의 props로 들어간다.
나는 여기서 banana를 button의 텍스트로 사용할 것이므로
button 함수를
function Btn(props) {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10
}}>{props.banana}</button>
);
}
이와 같이 작성해준다.
props.banana
에서 props 오브젝트의 banana 값만을 가져온다. 만약 매개변수로 사용할 값이 오직 banana 뿐이라면
function Btn({banana}) {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10
}}>{banana}</button>
);
}
와 같이 banana자체를 매개변수 값으로 지정해줄 수도 있다.
또한 useState를 사용하여 value값을 바꾸는 함수도 props로 줄 수 있다.
useState선언 및 setValue선언
const [value, setValue] = React.useState("Save Changes"); const changeValue = () => setValue("Revert Changes");
value값 및 changeValue함수 props로 전달
<Btn text={value} changeValue={changeValue} /> <Btn text="Continue" />
Btn 함수의 onclick리스너에 changeValue 할당
function Btn({ text, changeValue }) { return ( <button onClick={changeValue} style={{ backgroundColor: "tomato", color: "white", padding: "10px 20px", border: 0, borderRadius: 10 }}>{text}</button> ); }
이wp SaveChanges 버튼을 클릭하면 Revert Changes로 텍스트가 바뀐다. 그런데 이 과정에서 text가 Continue인 것 까지 렌더링이 다시 된다. 부모 요소에서 state가 바뀌면서 리렌더링 되는 과정에서 자식들도 리렌더링되기 때문인데, React.memo
기능으로 바뀌지 않는 버튼의 리렌더링을 방지할 수 있다.
const MemorizedBtn = React.memo(Btn);
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Changes");
return (
<div>
<MemorizedBtn text={value} changeValue={changeValue} />
<MemorizedBtn text="Continue" />
</div>
);
}
이제 Continue를 텍스트로 가지는 버튼은 다른 버튼이 눌려 리렌더링이 되도 함께 다시 렌더링 되지 않아 메모리 소모를 줄일 수 있다.
Props의 형을 제한하는 조건을 줄 수 있다.
예를 들어
<div>
<Btn text={value} changeValue={changeValue} fontSize={18} />
<Btn text={14} />
</div>
다음과 같이 text가 string이 아닌 number이 들어가는 경우에 개발자나, 사용자에게 경고 문구를 해줘야 할 수 있다.
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
위 스크립트 파일을 가져오고,
Btn.propTypes = {
text: PropTypes.string.isRequired,
fontSize: PropTypes.number
};
버튼의 propTypes 속성을 정의해주면 된다. 형 외에 값을 둘 중 하나로 해야한다거나, 필수적으로 입력해야 되는 것 등의 조건을 지정해줄 수 있다.