😓 리액트를 너무 손 놨던것 같아서 노마드코더 영상을 보면서 다시 차근차근 공부해보려한다.
JSX는 react의 유일한 커스텀 개념이라고 생각하면된다. 따라서 vue, angular를 배울땐 JSX를 쓸 이유가 사라지는것이다.
src안에 자신이 좋아하는 파일명의 component를 만들어보자(니콜라스는 potato.js로 만들었다.)
component를 작성할 때 마다 import React from 'react';를 써주는것을 잊지말자! 만약 쓰지 않는다면 react는 jsx가 있는 component를 사용하는 것을 알 수 없기 때문이다.
import React from 'react';
//함수명은 대문자로 시작해주자
function Potato(){
return(
<h3> Hello Potato! </h3>
)
}
//export를 사용해 potato를 사용한다는것을 알려야한다.
export default Potato;
만들어진 potato를 어떻게 사용할까? index.js 파일을 보면 App을 사용할 때 다음과 같은 코드를 사용하고 있음을 알 수 있다.
import App from './App';
그렇다면 아래와 같은 코드를 사용해 넣을수 있는것일까?
//index.js 파일에서 넣어보자
import Potato from './Potato';
ReactDOM.render(
<React.StrictMode>
<App /><Potato /> {/* Patato를 App옆에 넣었다.*/}
</React.StrictMode>,
document.getElementById('root')
);
작동하지 않는 이뉴는 하나의 component만을 렌더링 해야하기 때문이고, 그 component는 현재 App이기 때문에 App 안에 넣어야 작동하는것을 볼 수 있다.
(해당 영상에서는 작동하지 않지만 21.08.08일인 지금은 2개의 컴포넌트도 렌더링이 된다.)
💡 "./파일명"을 해주는 이유
현재 App.js와 Potato.js는 src라는 같은 directory에 있기 때문에 "./"로 알려주는것
이제 아래와 같은 코드로 다시 만들어보자
//App.js에 Potato.js를 넣는것
function App() {
return (
<div>
<h1>Hello</h1>
<Potato />
</div>
);
}
react 서버로 가서 확인해보니 App.js에 써있는 'Hello!'와 Potato.js에 있는'Hello Potato!'가 나타나는것을 확인 할 수 있다.(어떻게 확인하는지 모르겠다면 제 블로그의 개념정리(react)를 봐주세요 🥺)
개발자 툴로 소스코드를 보면 react가 component를 가져와서 브라우저가 이해할 수 있는 평범한 html로 바꾼것을 확인 할 수 있다.(😁 이 방법 또한 이해하기 어렵다면 제 블로그를 참고해주세요)
이제 Potato를 지우고 App.js에서 작업을 하자!(계속 파일을 만들고 이동하면서 하고 싶지않기 때문에)
//다시 Potato를 만들고 싶다면 App.js파일 안에 아래와 같이 만들 수 있다.
function Potato() {
return (
<div>
<h3>Potato!!🤩</h3>
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Potato />
</div>
);
}
react는 재사용 가능한 component를 만들 수 있다는 장점이 있는데, 이 말은 component를 계속 반복 사용할 수 있다는 뜻이다. Potato를 Movie로 바꿔서 생각해보자. 20편의 영화 리스트를 가지고 있을 때, 를 20개씩 수동으로 만들면 비효율적이기도 하고 react를 사용 해야 할 이유도 없을 것이다. 따라서 수많은 영화 리스트를 동적으로 처리하기 위해선 component에서 자식 component로 정보를 보내는 방법을 알아야 한다.
이제 Potato대신 Food라고 바꾼뒤 application에서 food로 정보를 보내고 그 다음 food에서 받아온 정보를 어떻게 사용할지 알아보자
function Food() {
return (
<div>
<h3>Food!!🤩</h3>
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Food fav="kimchi"/> {/*html과 비슷한 방식인것을 볼 수 있다.*/}
</div>
);
}
food component에 정보를 보내는 방법은 위와 같은 코드로 만들수 있다. 현재는 정보는 보냈지만 정보를 사용하지 않았기 때문에 새로고침을 해도 변화가 없는것을 볼 수 있다. 하지만 우리가 한 일은 react의 첫 개념 중 하나인데 그것은 food component에 kimchi라는 value로 prop(property) name을 줬다는 것이다.
props(property의 축약어)를 어떻게 사용할까? react는 우리가 전달한 props를 가져가는 일을 할 수 있다. 따라서 우리는 부모에서 자식으로 전달 할 때 원하는 만큼 props를 보낼 수 있다.
예를 들어 food component로 정보를 보내려 한다면 react는 모든 props를 가져올것이고, food function component의 arg로 그것들을 넣을것이다.
function Food(props) {
console.log(props)
return (
<div>
<h3>Food!!🤩</h3>
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Food fav = "kimchi" someting = {['Jetom', 1, 2, 3, 4]}/>
</div>
);
}
실제로 console.log로 확인하니 props가 찍힌것을 볼 수있다. props는 obj이므로 아래와 같은 코드로 접근할 수 있다.
//fav만 남기고 나머지 props는 지웠다.
function Food(props) {
console.log(props.fav)
return (
<div>
<h3>Food!!🤩</h3>
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Food fav = "kimchi"/>
</div>
);
}
(작고 소중한 kimchi가 찍혔다.)
이제 props의 내부 값인 fav를 꺼내려한다면 아래와 같은 코드를 사용해보자
//p
function Food({fav}) {
//props.fav와 같은 방법이다.
return (
<div>
<h3>{fav}!!🤩</h3> {/*이곳에 fav를 넣어준다면 food에서 kimchi가 될것이다.*/}
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Food fav = "kimchi"/>
</div>
);
}
이제 다른 component를 만드려면 아래와 같이 작성할 수 있다. 이것이 (jsx와 props로 component를 재사용할 수 있는 방법이다.)
function Food({ fav }) {
return (
<div>
<h3>{fav}!!🤩</h3>
</div>
)
}
function App() {
return (
<div>
<h1>Hello</h1>
<Food fav="kimchi 🇰🇷" />
<Food fav="banana 🍌" />
<Food fav="strawberry 🍓" />
<Food fav="meet 🍖" />
</div>
);
}
//food의 fav는 하나인데 App에서 만든 compoent에 따라 나타나는것 을 볼 수 있다.
우리는 App compoent에 새로운 음식을 추가 할 때마다 복사 & 붙여넣기를 하기때문에 이것은 효율적이지 않았다. 이런 복사 & 붙여넣기를 하는 이유는 처음부터 데이터를 가지고 있지 않았기 때문이다. 따라서 웹사이트의 동적 데이터는 어떤식으로 추가 하는지 지금부터 알아보겠다.
우선 데이터가 이미 API에서 왔다고 가정 해보기 위해선 먼저 함수를 만들고 그 함수명은 foodILike로 불리는 array라고 만들자 (이 foodILike는 food obj의 배열이 될것이다.)
function Food({ fav }) {
return (
<div>
<h3>{fav}!!🤩</h3>
</div>
)
}
//arr안에 obj로 음식과 이미지를 담았다.
const foodILike = [
{
name: 'kimchi 🇰🇷',
image: 'http://08food.com/web/product/big/201801/33_shop1_243196.jpg'
},
{
name: 'banana 🍌',
image: 'https://src.hidoc.co.kr/image/lib/2020/12/11/1607668328502_0.jpg'
},
{
name: 'strawberry 🍓',
image: 'http://www.foodnmed.com/news/photo/201802/12728_2384_0900.jpg'
},
{
name: 'meet 🍖',
image: 'http://www.foodnmed.com/news/photo/201812/17332_3510_1310.jpg'
}
]
function App() {
return (
<div>
<h1>Hello</h1>
{/*이곳에 list를 담을 예정*/}
</div>
);
}
이제 어떻게 하면 자동적으로 array를 가져와서 렌더링을 할까? 정답은 javascript의 map을 이용하는것이다. map을 간단하게 살펴보자
📝 map()
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
const dog = ['jetom', 'rari'];
//element에 return 0을 해주면 배열에 차례대로 0이 담기는것을 볼 수 있다.
dog.map(item => {console.log(item); return 0});
//arrow function을 사용하지 않을땐 다음과 같이 나타낸다.
dog.map(function(item){console.log(item); return 0});
map을 가지고 이번엔 dog element에 '🐶'를 추가해보겠다.
const dog = ['jetom', 'rari'];
//꼭 item이라 붙힐 필요없다.
dog.map(item => `${item} 🐶`);
map에 대해 알았으니 다시 react로 돌아가서 원하는 결과를 출력하자
//name이 필요해서 name으로 바꿔줬다.
function Food({ name }) {
return (
<div>
<h3>{name}!!🤩</h3>
</div>
)
}
//foodILike 코드 생략
//현재 eat는 obj이며, obj 값을 가져오는 방식을 통해서 다음과 같이 입력하면된다.
function App() {
return (
<div>
{/* object를 가져오는게 이해가 안간다면 제 블로그에서 객체를 봐주세요^^ㅎㅎ*/}
{foodILike.map(eat => <Food name ={eat.name}}/> )}
</div>
);
}
위의 코드대로 만들었다면 복사 + 붙여넣기를 일일이 했던 방식과 같은 결과를 확인 할 수 있다.
같은 방법으로 img(image)를 가져오려면 아래의 코드와 같이 입력하면된다.
//name 다음으로 picture를 props로 받아줬다.
function Food({ name, picture }) {
return (
<div>
<div>
{/*h1에서 코드를 수정했다.*/}
<h2>{name}!!🤩</h2>
<img src={picture}/>
</div>
</div>
)
}
function App() {
return (
<div>
{foodILike.map(eat => <Food name ={eat.name}, picture = {eat.image}/> )}
</div>
);
}