상꼬롬(?)한 월요일임니다 여러분.
오늘도 강의듣다가 지친 림졍, 인사올립니다.
부운명... 주말에 주기로 하셨던 강의는
오늘 업로드가 되어 우다다다 듣기 시작했고..요 (결론 : 합법적 변명 쌉가능.)
특강 듣다가 코드 타임어택이라는 엄청난 이벤트에 오열도 좀 하구요...
좀.. 할게 많네요. 레쯔고.
React (리액트) 강의 정리 - 숙련 ver.
분명 주차는 1개인데... 시간은 2주치랑 똑같은뎁쇼..?
Styled- Components
CSS-in-JS
CSS코드, JS(JavaScript) 활용하여 작성, 컴포넌트 꾸며줌, 조건문, 변수 등 다양한 로직 이용 가능
(이제 꾸밀 때 css만들어서 import하고... 각 태그마다 classname을 안넣어도 되는 시대야.)
벗-뜨 작성하려면 패키지 필요, 그 패키지 중 하나가 바로 Styled-Components.
Styled-Components
CSS-in-JS 방식의 라이브러리, React의 컴포넌트를 꾸밀 수 있게 도와주는 *패키지.
* 패키지: React에 없는 기능, 추가로 가져와 사용할 수 있는 써드파티(third-party) 프로그램 npm에 모여 있음 (누군가에 의해 생성)
→ 사용하고자 하는 패키지를 npm install or yarn add 활용하여 설치 및 사용 가능
- 설치 및 사용법
<설치>
1) VsCode에 [vsCode-styled-components] 라는 친구 검색 후, 설치.
(내부 스타일 코드 편하게 작성하기 위해 사용)
2) VsCode 터미널 열고, 아래 명령어 입력해서 패키지 설치해주면.. 끝.
yarn add styled-components
<사용법>
- 기본적인 사용법 : 꾸미고자 하는 컴포넌트, SC의 방식대로 먼저 만든 후 그 안에 스타일 코드를 작성하는 방식으로 진행
( 백틱(`) 사용해서 작성, ' styled. ' 뒤에는 html 태그가 옴. )
// src/App.js
import React from "react";
// styled-components에서 styled 라는 키워드를 import 합니다.
import styled from "styled-components";
// styled키워드를 사용해서 styled-components 방식대로 컴포넌트를 만듭니다.
const StBox = styled.div`
// 그리고 이 안에 스타일 코드를 작성합니다. 스타일 코드는 우리가 알고 있는 css와 동일합니다.
width: 100px;
height: 100px;
border: 1px solid red;
margin: 20px;
`;
const App = () => {
// 그리고 우리가 만든 styled-components를 JSX에서 html 태그를 사용하듯이 사용합니다.
return <StBox>박스</StBox>;
};
export default App;
- 조건부 스타일링 : classname을 사용 시, styled-components를 이용하면 간편하게 할 수 있음.
( CSS-in-JS 방식을 활용하여 JS 작성하듯이 코드작성가능. )
+) 컴포넌트이기에.. props로 정보 전달 가능 ( props === 부모 컴포넌트 to 자식 컴포넌트, 정보 전달 시 사용! )
// src/App.js
import React from "react";
import styled from "styled-components";
// 1. styled-components를 만들었습니다.
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor}; // 4.부모 컴포넌트에서 보낸 props를 받아 사용합니다.
margin: 20px;
`;
const App = () => {
return (
<div>
{/* 2. 그리고 위에서 만든 styled-components를 사용했습니다. */}
{/* 3. 그리고 props를 통해 borderColor라는 값을 전달했습니다. */}
<StBox borderColor="red">빨간 박스</StBox>
<StBox borderColor="green">초록 박스</StBox>
<StBox borderColor="blue">파랑 박스</StBox>
</div>
);
};
export default App;
추가) map과 switch 문을 활용한 리팩토링
// src/App.js
import React from "react";
import styled from "styled-components";
const StContainer = styled.div`
display: flex;
`;
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor};
margin: 20px;
`;
// 박스의 색을 배열에 담습니다.
const boxList = ["red", "green", "blue"];
// 색을 넣으면, 이름을 반환해주는 함수를 만듭니다.
const getBoxName = (color) => {
switch (color) {
case "red":
return "빨간 박스";
case "green":
return "초록 박스";
case "blue":
return "파란 박스";
default:
return "검정 박스";
}
};
const App = () => {
return (
<StContainer>
{/* map을 이용해서 StBox를 반복하여 화면에 그립니다. */}
{boxList.map((box) => (
<StBox borderColor={box}>{getBoxName(box)}</StBox>
))}
</StContainer>
);
};
export default App;
Global Styles(전역 스타일링)
겹치고 반복되는 스타일링 적용 → 한번에 정리해서 깔쌈하게 하는게 좋겠져?
∴ 전역 스타일링(Global Styles) 탄생함.
예시)
공통된 부분 체킹, 새로운 파일명으로 따로 구분하여 뺀 다음 import로 가져와서 적용하면 끝.
- 적용 전
/* 공통 스타일링 부분 font-family: "Helvetica", "Arial", sans-serif; line-height: 1.5 */
import styled from "styled-components";
function TestPage(props) {
return (
<Wrapper>
<Title>{props.title}</Title>
<Contents>{props.contents}</Contents>
</Wrapper>
);
}
const Title = styled.h1`
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
font-size: 1.5rem;
margin: 0;
margin-bottom: 8px;
`;
const Contents = styled.p`
margin: 0;
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
font-size: 1rem;
`;
const Wrapper = styled.div`
border: 1px solid black;
border-radius: 8px;
padding: 20px;
margin: 16px auto;
max-width: 400px;
`;
export default TestPage;
- 적용 후
[GlobalStyle.jsx]
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
`;
export default GlobalStyle;
[BlogPost.jsx]
function BlogPost({ title, contents }) {
return (
<>
<p>{title}</p>
<p>{contents}</p>
</>
);
}
export default App;
[App.jsx]
import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";
function App() {
const title = '전역 스타일링 제목입니다.';
const contents = '전역 스타일링 내용입니다.';
return (
<>
<GlobalStyle />
<BlogPost title={title} contents={contents} />
</>
);
}
export default App;
크로스 브라우징
웹사이트 or 웹 어플리케이션이 다양한 브라우저 및 다양한 운영체제 환경에서 일관된 사용자 경험을 제공하도록 만드는 작업
각 브라우저만의 해석 및 렌더링 방식 차이 존재 → 여기서는 잘 작동하는데 다른 곳에서는 오류나 문제가 발생할 수도..
- 크로스 브라우징 이슈 : 각 브라우저마다 기본 스타일(default style)을 제공, 렌더링 시 브라우저마다 다르게 보이는 문제 발생
출력값이 각 브라우저마다 다르게 보일 수 있기 때문에.. ∴ css reset 필요.
- CSS Reset
1) 직접 CSS 파일 링크
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./reset.css" />
</head>
<body>
<span>Default Style을 테스트 해 봅니다.</span>
<h1>이건 h1 태그에요</h1>
<p>이건 p 태그에요</p>
</body>
</html>
2) reset css cdn 검색 후, 제공하는 코드 사용하기
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.2/reset.min.css">
useState
[App.jsx]
import { useState } from 'react'
import './App.css'
import Child from "./Child"
function App() {
const [count, setCount] = useState(0);
return (
<>
<div>
<h1>나는 부모 컴포넌트</h1>
<span>current count: {count}</span>
<Child setCount={setCount} />
</div>
</>
);
}
export default App;
[Child.jsx]
const Child = ({ setCount }) => {
return (
<div>
<h5>응애 나는 자식 컴포넌트</h5>
<button onClick={() => {
setCount((prev) => prev + 1);
}}>
누르면 성장한다..!
</button>
</div>
);
}
export default Child;
- 결과물
setCount, 자식에게 상속하여 코드를 작성 시, count 별도 상속 필요 X. setCount = prev(이전값) + 1
useEffect
useEffect: 어떤 컴포넌트가 화면에 보여졌을 때 or 어떤 컴포넌트가 화면에서 사라졌을 때 무언가를 실행하고 싶을 때 사용
import 해서 사용 (얘도 React에서 제공하는 훅이라.)
import React, { useEffect, useState } from "react";
const App = () => {
const [value, setValue] = useState("");
useEffect(() => {
console.log("앙녕 리펙트");
});
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
console.log("value => ", value);
}}
/>
</div>
);
}
export default App;
의존성 배열
이 배열에 값을 넣잖아? 그 값이 바뀔 때만 useEffect를 실행할게 s(^-^)v
// useEffect의 두번째 인자가 의존성 배열이 들어가는 곳 입니다.
useEffect(()=>{
// 실행하고 싶은 함수
}, [의존성배열])
If... 의존성 배열을 따로 설정해두지 않는다면..?
상태 바뀔때마다 계~속 함수를 실행하는 매우 어지러운 일이 발생하니.. 꼭 설정해두자. (잊지말긔 >_ㅇ)
- 의존성 배열에 빈 배열 [] 를 넣은 경우 (예시 참고)
// src/App.js
import React, { useEffect, useState } from "react";
const App = () => {
const [value, setValue] = useState("");
useEffect(() => {
console.log("hello useEffect");
}, []); // 한 번만 실행하고 싶을 땐, 비워두세요. 비움이 미학입니다(?)
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
/>
</div>
);
}
export default App;
- 값이 있는 의존성 배열 (예시 참고)
2번 찍히는 이유? strict mode 라는 개발 환경이기 때문.
strict mode 제거 방법 → main.jsx에서 <React.StrictMode> 제거
// src/App.js
import React, { useEffect, useState } from "react";
const App = () => {
const [value, setValue] = useState("");
useEffect(() => {
console.log("hello useEffect");
}, [value]); // value를 넣음
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
/>
</div>
);
}
export default App;
clean up
컴포넌트가 나타났을 때 (=== 렌더링됐을 때 === 함수 컴포넌트가 실행됐을 때) 동작하는 것? → useEffect, effect 함수
컴포넌트가 사라졌을 때 실행되는 것? → 클린 업(clean up)
useEffect 안에서 return 후, 이 부분에 실행되길 원하는 함수를 넣어주면 끝.
[기본 형태]
// src/App.js
import React, { useEffect } from "react";
const App = () => {
useEffect(()=>{
// 화면에 컴포넌트가 나타났을(mount) 때 실행하고자 하는 함수를 넣어주세요.
return ()=>{
// 화면에서 컴포넌트가 사라졌을(unmount) 때 실행하고자 하는 함수를 넣어주세요.
}
}, [])
return <div>hello react!</div>
};
export default App;
[예시 - 오늘도 등장한 도란스뽀머]
// src/Dorans.js
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
const 뿌라임 = () => {
const nav = useNavigate();
useEffect(() => {
return () => {
console.log(
"그대의 자격은 이미 증명되었다. 프라이머스께서 그대에게 명하셨도다. 받아라, 사이버트론의 미래와 리더십의 매트릭스를!"
);
};
}, []);
return (
<button
onClick={() => {
nav("/todos");
}}
>
짱멋진 뿌라임이 되기
</button>
);
};
export default 뿌라임;
마무리 - 강의와 TIL, 아주 끔찍한 딜레마에 빠졌다.
원래 림졍의 공부 스타일은 아래와 같다..
우선 강의를 들어! (안들려도 일단 들어!)
그러고 봐! (강의 자료를!)
다시 이해해! (어?)
되새김질 어게인!
이거..인뎁쇼.. 막상 이런 방식을 고수하다 보니 강의정리 TIL 작성이 버거운 그런 너낌이 있어서...
오늘은 조금 병행해보면서 집중을 해볼까... 는 무슨 이것도 벅차!
심지어 완벽주의 성깔 어디 안가고 또 나와서
혼자 이해 못하면 넌 못넘어가 히히 하고 스스로 통곡의 벽 창조하고 북치고 장구치고 다했답니다.. ^-^...
이번 부분 꽤 많이 엄청 중요하다고 했는데.. 조금 고민이군요.. 어찌해야하나..
일단 내일 최대한 많이 쓰고.. 지인짜 못한것만 다음날까지 하는거로...
림졍과 합의보기 끝(?)
아 졸려. 이제 그만 잘래.
KPT 회고
- Keep : 나름 월요일 알차게 보냄. 강의도 절반 정도 수강하긴 함..
- Problem : 근데 그것만큼.. 강의 정리를 못함.. 그래서 병행할까 해서 중간에 해봤는데 포기함 ㅎㅎ..
- Try : 중간 그 어딘가에서 합의 좀 잘 봐야 할듯. 매우. 중요. (별표 쫘아아아악)
T H E E N D.
'React TIL' 카테고리의 다른 글
[React] Day_34 데일리 정리 (1) | 2024.11.06 |
---|---|
[React] Day_33 데일리 정리 (2) | 2024.11.05 |
[React] Day_31 개인 프로젝트 후기 (3) | 2024.11.01 |
[React] Day_30 개인 프로젝트 중간점검 (0) | 2024.10.31 |
[React] Day_29 개인 프로젝트 중간점검 (1) | 2024.10.30 |