오늘은 정리할것이 많기 때문에 바로 본론으로 들어가겠다.
- Component를 사용했을때의 한계.
- component만 사용하면 재사용성이 떨어진다. 그 이유는 같은 행위를 반복적으로 많이 해줘야하기 때문. 이 문제를 props로 해결할 수 있다.
- 해당 이미지에 색상과 카드안에 메세지를 제외하면 나머지 코드는 똑같이 때문에 props를 이용해 더 간결하게 정리할 수 있다.
//<App.jsx> import CardA from "./components/CardA"; import CardB from "./components/CardB"; import CardC from "./components/CardC"; import CardD from "./components/CardD"; import CardE from "./components/CardE"; import CardF from "./components/CardF"; function App() { return ( <div className="min-h-screen p-40 grid grid-cols-4"> <CardA /> <CardB /> <CardC /> <CardD /> <CardE /> <CardF /> </div> ); } export default App;
//<components/CardA.jsx> (B, C, … , F 동일) function CardA() { return <div className="bg-red-100 w-40 h-60">A</div>; } export default CardA;
//<components/Card.jsx> function Card(props) { return <div className={`${props.color} w-30 h-30`}>{props.name}</div>; } export default Card;
쉽게 설명하기 위해서 component부터 보도록 하겠다. 위에서 사용했던 component에 있던 코드와는 다르게 class안에 color부분을 {`${props.color}로 변경해줌으로서 App.jsx에 입력만하면 props를 적용한코드 외에 나머지 코드로 여러가지 값을 만들어낼 수 있도록 하였다. 또한, 뒤에 {props.name}을 사용하여 App.jsx에 원하는 값을 입력하면 도출될 수 있도록 코드가 작성되었다.
❗여기서 중요한점은 단순히 component를 사용했을때는 원하는것을 만들기 위해서는 component에 계속해서 .jsx를 만들어줬어야 했는데 props를 사용하면 하나의 .jsx만으로 App.jsx에서 코드가 겹치는 부분에 한하여 내가 원하는 동일한 값을 계속 만들어낼 수 있다.
//<App.jsx> import Card from "./components/Card"; function App() { return ( <div className="min-h-screen grid grid-cols-4 gap-2"> <Card color="bg-red-100" name="A" /> <Card color="bg-orange-100" name="B" /> <Card color="bg-yellow-100" name="C" /> <Card color="bg-green-100" name="D" /> <Card color="bg-blue-100" name="E" /> <Card color="bg-purple-100" name="F" /> </div> ); } export default App;
위와같이 component를 props를 이용해 정리하고 나면 App.jsx에서 간단하게 동일한 코드를 쉽게 만들어낼 수 있다. 예를들면 다음과 같다.
const fruits = ["Apple", "Banana", "Kiwi", "Orange"]; // 각각의 요소들을 꺼내서 사용하고 싶은 상황. const APPLE = fruits[0]; const BANANA = fruits[1]; const KIWI = fruits[2]; const ORANGE = fruits[3]; console.log(APPLE); console.log(BANANA); console.log(KIWI); console.log(ORANGE);
const myProfile = { name: "h662", age: 18, job: "student", genius: true, }; // 이름만 필요한 상황. console.log(myProfile.name);
구조분해에서 배열과 객체는 사용방법이 다르다.
배열은 [ ]를 사용하고, 요소들이 순서를 가지고 있다.
// let은 한번에 여러 변수를 생성할 수 있다. let apple, banaba, kiwi, orange; // 배열로 감싸야하고 순서가 존재한다. [apple, banaba, kiwi, orange] = ["Apple", "Banana", "Kiwi", "Orange"]; console.log(apple); console.log(banaba); console.log(kiwi); console.log(orange);
const myProfile = { codeName: "Dio", age: 28, job: "student", genius: true, }; // 순서가 상관없고 내가 원하는 요소만 가지고 올 수 있습니다. const { job, codeName } = myProfile; console.log(codeName); console.log(job);
자바스크립트 배열에서 반복되는 요소를 처리할때 Map함수를 사용할 수 있다.
먼저 기본적인 구조에 대해서 알아보자면.
위 이미지를 보면 v는 배열의 값을 나타내고, i는 배열의 인덱스번호를 나타내는것을 알수있다.
위 코드를 통해 결과값을 봤을때 i에 +1이 더해지며 위에 있는 과일이 순서가 정해지며 결과값이 나오는것을 확인할 수 있다. 이 결과값을 토대로 map함수를 사용해 배열의 요소를 하나씩 탐색할 수 있는것을 알수있다.
i를 사용하지 않는 경우 생략이 가능하다.
v를 가공해서 return을 할 경우 새로운 배열을 만들 수 있다.
"?" 가 같다를 뜻하고, ":"가 다르다를 뜻한다. 이걸 기준으로 props.day가 SUN이라면
? 앞에 나올때는 같다는 의미가 되어 위 이미지처럼 bg-red-400이 결과값이 되고, :가 나오면 다르다는 의미가 되어 또 다른 props.day로 넘어가게 된다.
거기서 조건이 SAT와 같냐 다르냐일때 ?로 같으면 bg-orange-400, :로 다르면 bg-blue-400 값이 나오게 된다는 기준을 만들어준다.
그리고 {props.date}를 통해 date에서 관련 데이터를 가져온다.
{props.todos.map((v, i) => {
return <li className="truncate">{v}</li>;
})}
위 {props.todos.map((v, i) => {} 에는 props와 map 함수가 포함되어있는데 props.todos를 통해 todos에서 관련 데이터를 가져오고, map 함수를 이용해 {v}만 사용하여 원하는 데이터를 가져올 수 있도록 했다.
Date.jsx까지 만들어지고 나면 Calendar.jsx에 map 함수를 사용하여 코드를 작성해줘야 한다.
calendarData.json에서 데이터를 가져오는데 기본적으로 map함수를 사용할때는 key={i}를 입력해야 한다. 그리고 각각 값을 불러올 수 있도록 date={v.date}, day={v.day}, todos={v.todos} 를 component로 만들어준다.
SPA(single page application)는 화면의 header나 footer, sidebar 등 다시 로드해도 변함이 없는 부분들은 그대로 유지한 채 변경되는 부분의 데이터만 가져와서 수정하는 웹사이트를 말한다.
React로 SPA를 구현한다는 것은 곧 해당 요청에 맞는 component만 routing하여 부분적으로 렌더링한다는 것을 의미한다. 이때 요청에 맞는 component를 매칭시키기 위해 react-router-dom을 사용한다.
react-router와 react-router-dom, react-router-native의 차이
react-router-dom은 웹에서 쓰이는 컴포넌트를 포함.
react-router-native는 react-native를 활용한 앱개발에 쓰이는 컴포넌트를 포함.
react-router는 이 둘을 합친 패키지.
"BrowserRouter"
react-router-dom의 라우터는 "BrowserRouter"와 "HashRouter" 두가지가 있다.
"BrowserRouter"는 HTML5의 history API를 활용하여 UI를 업데이트하고, "HashRouter"는 URL의 hash를 활용한 라우터입니다. 정적인(static)페이지에 적합하다.
보통 request와 response로 이루어지는 동적인 페이지를 제작하므로 "BrowserRouter"가 보편적으로 쓰인다.
"Route"
"Switch"
path의 충돌이 일어나지 않게 "Route"들을 관리한다.
"Swtich" 내부에 "Route"들을 넣으면 요청에 의해 매칭되는 "Route"들이 다수 있을 때에 제일 처음 매칭되는 "Route"만 선별하여 실행하기 때문에 충돌 오류를 방지해주며, "Route"간에 이동 시 발생할 수 있는 충돌도 막아줍니다.
path와 매칭되는 "Route"가 없을 때에 맨 밑에 default "Route"의 실행이 보장된다.(path 속성을 명시하지 않은"Route")
다음은 헤더를 만든다. 헤더도 component에 만든다.
위 header className을 통해 푸터와 같이 유지되는 공간을 만들어주고, 하단에 link를 걸어줄 button을 만든다.
button을 만들고 나면 해당 button에 색상과 style을 작성한다. style은 index.css에 btnstyle로 만들어 언제든지 가져와서 사용할 수 있도록 만들었다.
button까지 완성하고 나면 link를 만들어주어야 하는데 button을 감싸도록 만들고 link to= 를 작성하여 해당 링크를 가져올 수 있도록 한다.
헤더와 푸터까지 만들고 링크에 들어갈 페이지와 링크연결 코드까지 작성하고 나면 실행될 수 있도록 App.jsx 작성에 들어간다.
가장 상단부터 import로 가져올 수 있는 코드를 작성해준다.
BrowserRouter, Routes, Route가 실행될 수 있도록 하는 코드.
A, B, C, Main, NotFound 가 실행될 수 있도록 하는 하는 코드.
Header와 Footer가 실행될 수 있도록 하는 코드.
BrowserRouter로 가장 밖깥쪽을 감싸준다.
이후 가장 상단에 위치할 Header를 Routes위에 위치시킨다.
Routes 안에 Routing이 되는 페이지들을 위치시킨다.
/Routes 밑에 가장 하단에 있어야할 Footer를 위치시킨다.
마지막으로 /BrowserRouter 로 다시 감싼다.
오늘 하루동안 너무 많은걸 배워서 사실 제대로 작성한지도 모르겠다. 그래도 이전보다는 오늘 배운내용이 이해가 좀더 됐다고 생각되어 작성하는데 큰 무리는 없었던 것 같다. 물론 이게 맞는내용인지는 모르겠지만 최대한 내가 이해되었던 내용을 글로 옮겨적어봤다. 작성하면서 다시 생각하게 된 부분도 많고 머릿속에 한번 더 넣을 수 있어서 좋았다. 물론 맞는 내용인지는 모르겠지만; 특히 React Router는 어떻게 사용되는지는 이해가 되었는데 말로 설명하기가 참 어렵다. 물론 다른것도 그렇기는 하지만 유난히 더 어렵다. 이외에도 삼항연산자나 fakeuseState, for문, if문, else문 등 중간중간 다른것들도 배워서 오늘은 정말 머리가 터질지경이다. 그래도 정리를 해놓으니 머릿속에 떠돌던 것들도 정리된 기분이다. 내일은 더 어려운걸 배운다고 하는데.. 감당이 될지 모르겠다.. 일단 이해하는데까지 이해해보고 이번주는 금요일이 휴강이니 다시 내 시간을 녹여 머릿속에 넣는수밖에.. 그래도 오늘은 지난주 금요일과는 다르게 뿌듯하다. 한번 멘탈 흔들리고 나니 조금 성장한 거 같은 느낌이다!