~4.3까지의 강의~
앞선 강의에서, 우리는 logic을 가지고 말 그대로 JSX를 분리된 component로 만들었다. (<MilestoKim /> 이런거)
props는 부모 component로부터 자식 component에 데이터를 보낼 수 있게 해주는 방법이다. 앞서서, 자식 component는 부모 component의 데이터를 필요로 하지 않고, 독립적이 었다. (자식 component는 <MiletoKim />이런거 였고, 부모는 <App/>이었음)
이제, 부모 component로부터 자식 component로 데이터를 보내보자. 그 전에 props로 해결이 가능하게 될 문제들을 가정해보자. 어플리케이션은 다양한 버튼을 가지고 있는데, 어떻게 리액트 component를 재사용 할 수 있을까?!
component는 단지 JSX를 반환하는 함수이다. 그게 component이다.
먼저, 스타일을 넣어주자. 스타일을 바꾸는 방법에는 여러가지가 있지만, 기본적으로 버튼의 style 요소를 사용해 스타일을 변경해보자.
<button
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10,
>
그런데, 버튼을 2개 사용하는 과정에서, 스타일을 재사용하고 싶어졌다.
how?? ->img 태그에 지정하는거랑 비슷한 방법으로 사용한다.
function Btn(props){
console.log(props);
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10
}}
>
{props.banana}
</button>
);
}
function App(){
return(
<div>
<Btn banana="Save Changes" />
<Btn banana="Confirm" />
</div>
);
}
<Btn banana="Save Changes" />
Btn({banana:"Save Changes"})
function Btn({text,big}){
//console.log(text, big);
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10,
fontSize: big ? 18 : 16,
}}
>
{text}
</button>
);
}
function App(){
return(
<div>
<Btn text="Save Changes" big={true} />
<Btn text="Confirm" big={false}/>
</div>
);
}
그런데, props의 이름을 변경한다면 동시에 component의 이름도 바꾸어야 한다. 반영된게 위의 코드
전체 코드
<!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">
function Btn({text,big}){
//console.log(text, big);
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10,
fontSize: big ? 18 : 16,
}}
>
{text}
</button>
);
}
function App(){
return(
<div>
<Btn text="Save Changes" big={true} />
<Btn text="Confirm" big={false}/>
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App/ >, root);
</script>
</html>
결론 : 자식이 부모에 prop으로 값 전달한다. 이름은 동일 해야 한다. prop을 사용하면 최대한 재사용할 수 있다.
props에 뭘 또 넣을 수 있는지 보자. 그리고 버튼을 rendering하는 component도 알아보자.
<Btn text={value} onClick={changeValue} />
위의 코드에서, onClick은 이벤트 리스너가 아니라, prop이다. 이름이 같을지도 모르겠지만, 리액트가 이벤트 리스너를 추가시키는 게 아니다. prop의 이름이다! 만약에 버튼을 클릭하면, 어디에도 onClick은 없는 것이다. 이것은 버튼으로 들어가는 무엇인가가 아니라, Btn component로 들어가는 무엇인가 이다. 그러나 prop으로 뭐든 넣으면 자동적으로 return 되는 것이 아니라 항상 우리가 써줘야 한다! (최종 코드에서는 이름 변경함)
const MemorizedBtn = React.memo(Btn);
//일반
return(
<div>
<Btn text={value} changeValue={changeValue} />
<Btn text="bye" />
</div>
);
//React Memo
return(
<div>
<MemorizedBtn text={value} changeValue={changeValue} />
<MemorizedBtn text="bye" />
</div>
);
전체코드
<!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">
function Btn({ text, changeValue }){
console.log(text, "was rendered");
return (
<button
onClick={changeValue}
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10,
}}
>
{text}
</button>
);
}
const MemorizedBtn = React.memo(Btn);
function App(){
const [value,setValue]=React.useState("Save Changes");
const changeValue=()=> setValue("Revert Changes");
/*return(
<div>
<Btn text={value} changeValue={changeValue} />
<Btn text="bye" />
</div>
);*/
//React Memo
return(
<div>
<MemorizedBtn text={value} changeValue={changeValue} />
<MemorizedBtn text="bye" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App/ >, root);
</script>
</html>
component가 아주 많을 때 실수가 생길 수도 있다. 이 때 proptype은 어떤 타입의 prop을 받고 있는지 체크해준다.
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
Btn.propTypes = {
text : PropTypes.string.isRequired,
fontSize : PropTypes.number,
}
전체 코드
<!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 src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script type="text/babel">
function Btn({text, fontSize = 14}){
console.log(text, "was rendered");
return (
<button
onClick={changeValue}
style={{
backgroundColor: "tomato",
color: "white",
padding:"10px 20px",
border:0,
borderRadius:10,
fontSize,
}}
>
{text}
</button>
);
}
Btn.propTypes = {
text : PropTypes.string.isRequired,
fontSize : PropTypes.number,
}
function App(){
return(
<div>
<Btn text="Save Changes" fontSize={18} />
<Btn text="Confirm" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App/ >, root);
</script>
</html>
결론: 설정 가능한 component를 갖는다는건 훌륭하다. 최대한 재사용할 수 있다. 우리는 복붙하는 대신 Btn component를 만든 것이다. prop들은 단지 인자를 사용해 component에 데이터를 보내기 위한 것이다.
prop에 접근하는 것은 첫 번쨰 인자 안에서 가능하다. 첫번째 인자에서 prop들을 하나의 오브젝트로서 받는 것이다. 접근하고 싶으면 component 이름은 전달할때와 받아서할 때랑 이름이 동일해야 한다.
우리는 재사용할 수 있게끔 component 사용하는 방법을 배웠다.
'Web Service > React' 카테고리의 다른 글
[영화 웹 서비스 만들기] #8. Effects (0) | 2022.03.24 |
---|---|
[영화 웹 서비스 만들기] #7. Create REACT App (0) | 2022.03.23 |
[영화 웹 서비스 만들기] #5. State (0) | 2022.03.21 |
[Next.js] Vercel 오류 및 Next.js 구조 (0) | 2022.03.19 |
[영화 웹 서비스 만들기] #4. setState (0) | 2022.03.19 |
댓글