์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- ๋ด์ฅ๊ณ ์ฐจํจ์
- @redux-toolkit
- removeCookie
- JS#3์ผ์ฐจ๋ฌ๋ฆฌ์#์ด๋ฐ์ธ๋ฐ#์๊ฐ๊ธ๋ฐฉ~
- ์๋ฐ์คํฌ๋ฆฝํธ#JS#var#let#const#undefined#null
- UX
- js
- dom
- children vs childrenNodes
- ์๋ฐ์คํฌ๋ฆฝํธ
- https://dasima.xyz/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%A0%9C%EA%B3%B1-math-pow-%EA%B3%84%EC%82%B0/
- slice/splice/split
- variable#function
- https://lo-victoria.com/introduction-to-redux-toolkit-for-beginners
- ์๋ฐ์คํฌ๋ฆฝํธ#JS#slice#splice
- react
- User Flow
- ใทใ
- redux์ํ์ ์ง
- ์๋ฐ์คํฌ๋ฆฝํธ#์กฐ๊ฑด๋ฌธ#๋ฌธ์์ด
- cmarket
- UI
- ๋ ธ๋๊ต๊ณผ์
- for~in/for~of
- https://developer-talk.tistory.com/299
- CSS
- ํท๊ฐ๋ฆฐ๋ค~
- toString#String
- Beesbeesbees
- https://www.daleseo.com/js-array-slice-splice/
- Today
- Total
Daily Front_Minhhk
[React] Custom Component ๋ณธ๋ฌธ
CDD, styled-Component , storybook, useRef
๐ Component Driven Development (CDD)
๋์์ธ๊ณผ ๊ฐ๋ฐ ๋จ๊ณ์์๋ถํฐ ์ฌ์ฌ์ฉํ ์ ์๋ UI ์ปดํฌ๋ํธ๋ฅผ ๋ฏธ๋ฆฌ ๋์์ธํ๊ณ ๊ฐ๋ฐ
→
๋ ๊ณ ์ฒ๋ผ ์กฐ๋ฆฝํด ๋๊ฐ ์ ์๋ ๋ถํ ๋จ์๋ก UI ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋๊ฐ๋ ๊ฐ๋ฐ ์ ์งํ
(์ปดํฌ๋ํธ ๋จ์๋ก ๋ง๋ค์ด ํ์ด์ง๋ฅผ ์กฐ๋ฆฝํ๋ ๊ฐ๋ฐ ๋ฐฉ์์ธ ์ํฅ์ ๊ฐ๋ฐ)
๐ CSS ์ ์ฒ๋ฆฌ๊ธฐ(CSS Preprocessor)
CSS๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์์ฑ๋ ์ ์๊ฒ ๋์์ ์ฃผ๋ ๋๊ตฌ
→
CSS ์ ์ฒ๋ฆฌ๊ธฐ ๋ก๋ ์น ์๋ฒ๊ฐ ์ธ์งํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๊ฐ CSS ์ ์ฒ๋ฆฌ๊ธฐ์ ๋ง๋ Compiler๋ฅผ ์ฌ์ฉํด์ผ ํ๊ณ ์ปดํ์ผ์ ํ๊ฒ ๋๋ฉด ์ค์ ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ CSS ๋ฌธ์๋ก ๋ณํ
Sass(Syntactically Awesome Style Sheets)
์๋ฐ์คํฌ๋ฆฝํธ์ฒ๋ผ ํน์ ์์ฑ์ ๋ณ์๋ก ์ ์ธํด ์ ์ฉ ํ ์ ์๋ค.
๋ฐ๋ณต๋๋ ์ฝ๋๋ฅผ ํ๋ฒ์ ์ ์ธ์ผ๋ก ์ฌ๋ฌ๊ณณ์ ์ฌ์ฌ์ฉ ํ ์์๋ค.
๐ ๋ฌธ์ ๊ฐ ๋ฐ์
⇒
์คํ์ผ์ด ๊ฒน์น๋ ๋ฌธ์ ํด๊ฒฐ์ํด ๊ณ์ธต ๊ตฌ์กฐ ๋ง๋ค์ด ์์ง → ์ฉ๋์ด ๋๋ฌด ์ปค์ก๋ค~
css์์๋ ์บก์ํ์ ์ค์์ฑ ์ฆ๊ฐ!!
CSS-in-JS
→
Styled-Component
๊ธฐ๋ฅ์ ์ด๊ฑฐ๋ ์ํ๋ฅผ ๊ฐ์ง ์ปดํฌ๋ํธ๋ค๋ก๋ถํฐ UI๋ฅผ ์์ ํ ๋ถ๋ฆฌํด ์ฌ์ฉํ ์ ์๋ค.
css๋ฅผ ์ปดํฌ๋ํธ ์์ผ๋ก ์บก์ํ,, ๋ค์ด๋ฐ์ด๋ ์ต์ ํ๋ฅผ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค!
→
๋น ๋ฅธ ํ์ด์ง ๋ก๋์ ๋ถ๋ฆฌํ๋ค๋ ๋จ์ ์ด ์์
๐ styled Components
1. styled Components ์ค์น
# with npm
$ npm install --save styled-components
# with yarn
$ yarn add styled-components
2. ์ปดํฌ๋ํธ ํ์ฉ
import styled from "styled-components";
const ์ปดํฌ๋ํธ์ด๋ฆ = styled.ํ๊ทธ์ข
๋ฅ`
background: black;
color: white;
`;
์ปดํฌ๋ํธ๋ฅผ ์ ์ธํ ํ [ styled.ํ๊ทธ ]๋ฅผ ํ ๋นํ๊ณ , ๋ฐฑํฑ ์์ ๊ธฐ์กด์ CSS๋ฅผ ์์ฑํ๋ ๋ฌธ๋ฒ๊ณผ ๋๊ฐ์ด ์คํ์ผ ์์ฑ์ ์์ฑ!
์ด๋ ๊ฒ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ React ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฏ ๋ฆฌํด๋ฌธ ์์ ์์ฑํด์ฃผ๋ฉด ์คํ์ผ์ด ์ ์ฉ๋ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
2-1. ์ปดํฌ๋ํธ๋ฅผ ์ฌํ์ฉํด์ ์๋ก์ด ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
import styled from "styled-components";
const button1 = styled.button`
background: black;
color: white;
`;
// const ์ปดํฌ๋ํธ์ด๋ฆ = styled.(์ฌํ์ฉํ ์ปดํฌ๋ํธ)
const button2 = styled.button1`
padding: 10px;
margin-top: 10px;
`;
3. Props ํ์ฉ
3-1. Props๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋งํ๊ธฐ
import styled from "styled-components";
//๋ฐ์์จ prop์ ๋ฐ๋ผ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ด ๊ฐ๋ฅํฉ๋๋ค.
const Button1 = styled.button`
background: ${(props) => (props.skyblue ? "skyblue" : "white")};
`;
export default function App() {
return (
<>
<Button1>Button1</Button1>
<Button1 skyblue>Button1</Button1>
</>
);
}
๊ฒฐ๊ณผ๋?!
3-2. Props ๊ฐ์ผ๋ก ๋ ๋๋งํ๊ธฐ
import styled from "styled-components";
//๋ฐ์์จ prop ๊ฐ์ ๊ทธ๋๋ก ์ด์ฉํด ๋ ๋๋งํ ์๋ ์์ต๋๋ค
const Button1 = styled.button`
background: ${(props) => (props.color ? props.color : "white")};
`;
//๋ค์๊ณผ ๊ฐ์ ํ์์ผ๋ก๋ ํ์ฉํ ์ ์์ต๋๋ค.
const Button2 = styled.button`
background: ${(props) => props.color || "white"};
`;
export default function App() {
return (
<>
<Button1>Button1</Button1>
<Button1 color="orange">Button1</Button1>
<Button1 color="tomato">Button1</Button1>
<br />
<Button2>Button2</Button2>
<Button2 color="pink">Button2</Button2>
<Button2 color="turquoise">Button2</Button2>
</>
);
}
๊ฒฐ๊ณผ๋ ์ด๋ ๊ฒ~~
4. ์ ์ญ ์คํ์ผ ์ค์
Styled Components์์ createGlobalStyle ํจ์๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
→
๊ทธ ๋ค์ ์ด ํจ์๋ฅผ ์ฌ์ฉํด CSS ํ์ผ์์ ์์ฑํ๋ฏ ์ค์ ํด์ฃผ๊ณ ์ถ์ ์คํ์ผ์ ์์ฑ!
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
padding : 5px;
margin : 2px;
border-radius : 5px;
}
`
๋ค์ >>
์ด๋ ๊ฒ ๋ง๋ค์ด์ง <GlobalStyle> ์ปดํฌ๋ํธ๋ฅผ ์ต์์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํด์ฃผ๋ฉด
์ ์ญ์ <GlobalStyle> ์ปดํฌ๋ํธ์ ์คํ์ผ์ด ์ ์ฉ!
function App() {
return (
<>
<GlobalStyle />
<Button>์ ์ญ ์คํ์ผ ์ ์ฉํ๊ธฐ</Button>
</>);
}
๐ Storybook
Storybook
npx create-react-app storybook-practice
ํด๋๊ฐ ์์ฑ๋๋ฉด, ํด๋ ์์์ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ์ฌ Storybook์ ์ค์น
npx storybook init
์ด์ ํฐ๋ฏธ๋ ์ฐฝ์ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ์ฌ Storybook์ ์คํ
npm run storybook
์ด์ ๊ฐ๋จํ ์คํ ๋ฆฌ๋ฅผ ์ง์ ์์ฑ์ ์ํด
1.
src ํด๋ ์์ Title.js ํ์ผ์ ํ๋ ๋ง๋ค๊ณ , ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ React ์ปดํฌ๋ํธ๋ฅผ ํ๋ ๋ง๋ค์ด export ํด์ค๋๋ค.
import React from "react";
// title์ h1 ์์์ textContent, textColor์ ๊ธ์์์ด ๋๋ props์
๋๋ค.
const Title = ({title, textColor}) => (
<h1 style={{color: textColor}}>{title}</h1>);
export default Title;
2.
๊ฐ์ ์์น์ธ src ํด๋ ์์ Title.stories.js ํ์ผ์ ํ๋ ๋ง๋ญ๋๋ค.
.stories๋ฅผ ๋ถ์ฌ ํ์ผ์ ๋ง๋ค๋ฉด ์์์ ์คํ ๋ฆฌ๋ก ์ธ์ํฉ๋๋ค.
Title.stories.js ๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
// ์์์ ์์ฑํ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
import Title from "./Title";
// title : ์ปดํฌ๋ํธ ์ด๋ฆ์ผ๋ก, '/'๋ฅผ ๋ฃ์ด ์นดํ
๊ณ ๋ฆฌํ ํ ์ ์์ต๋๋ค.
// ์ดํ ์์์์ ์กฐ๊ธ ๋ ์์ธํ ์ค๋ช
ํฉ๋๋ค.
// component : ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์์ ์คํ ๋ฆฌ๋ก ๋ง๋ค ๊ฒ์ธ์ง ๋ช
์ํฉ๋๋ค.
// argTypes : ์ปดํฌ๋ํธ์ ํ์ํ ์ ๋ฌ์ธ์์ ์ข
๋ฅ์ ํ์
์ ์ ํด์ค๋๋ค.
// ์ง๊ธ์ title, textColor์ด๋ผ๋ ์ ๋ฌ์ธ์์ text ํ์
์ด ํ์ํจ์ ์๋ฏธํฉ๋๋ค.
export default {
title: "Practice/Title",
component: Title,
argTypes: {
title: { control: "text" },
textColor: {control: "text"}
}
}
// ํ
ํ๋ฆฟ์ ๋ง๋ค์ด์ค๋๋ค. ์ด ํ
ํ๋ฆฟ์์๋
// Title ์ปดํฌ๋ํธ๊ฐ args๋ฅผ ์ ๋ฌ๋ฐ์ props๋ก ๋ด๋ ค์ค๋๋ค.
const Template = (args) => <Title {...args} />// Storybook์์ ํ์ธํ๊ณ ์ถ์ ์ปดํฌ๋ํธ๋ export const๋ก ์์ฑํฉ๋๋ค.
// ํ
ํ๋ฆฟ์ ์ฌ์ฉํ์ฌ Storybook์ ๋ฃ์ด์ค ์คํ ๋ฆฌ๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ์์ต๋๋ค.
// Template.bins({}); ๋ ์ ํด์ง ๋ฌธ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค.
export const RedTitle = Template.bind({});
// ๋ง๋ค์ด์ค ์คํ ๋ฆฌ์ ์ ๋ฌ์ธ์๋ฅผ ์์ฑํด์ค๋๋ค.
RedTitle.args= {
title: "Red Title",
textColor: "red"
}
// ์คํ ๋ฆฌ๋ฅผ ํ๋ ๋ ๋ง๋ญ๋๋ค.
export const BlueTitle = Template.bind({});
// ์คํ ๋ฆฌ์ ์ ๋ฌ์ธ์๋ฅผ ์์ฑํด์ค๋๋ค.
BlueTitle.args= {
title: "Blue Title",
textColor: "blue"
}
๊ฒฐ๊ณผ๋??
๊ฒฐ๊ณผ ์ด๋ฏธ์ง์ ๊ฐ์ด ์๋ ์์ฑ์ ๋ฃ์ด์ค title, textColor์ ๋ค๋ฅธ ๊ฐ์ ๋ฃ์ด ๋ณ๊ฒฝ ํ ์ ์๋ค.
๐ useRef( )
DOM reference๋ฅผ ์ ํ์ฉํ ์ ์๋ useRef
React๋ ์ด๋ฐ ์์ธ์ ์ธ ์ํฉ์์ useRef ๋ก DOM ๋ ธ๋, ์๋ฆฌ๋จผํธ, ๊ทธ๋ฆฌ๊ณ React ์ปดํฌ๋ํธ ์ฃผ์๊ฐ์ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ์๋ ์์ ์ฝ๋์ฒ๋ผ ์์ฑํ์๋ฉด ์ฃผ์๊ฐ์ ํ์ฉํ ์ ์์ต๋๋ค.
const ์ฃผ์๊ฐ์_๋ด๋_๊ทธ๋ฆ = useRef(์ฐธ์กฐ์๋ฃํ)
// ์ด์ ์ฃผ์๊ฐ์_๋ด๋_๊ทธ๋ฆ ๋ณ์์ ์ด๋ค ์ฃผ์๊ฐ์ด๋ ๋ด์ ์ ์์ต๋๋ค.
return (
<div>
<input ref={์ฃผ์๊ฐ์_๋ด๋_๊ทธ๋ฆ} type="text" />
{/* React์์ ์ฌ์ฉ ๊ฐ๋ฅํ ref๋ผ๋ ์์ฑ์ ์ฃผ์๊ฐ์_๋ด๋_๊ทธ๋ฆ์ ๊ฐ์ผ๋ก ํ ๋นํ๋ฉด*/}
{/* ์ฃผ์๊ฐ์_๋ด๋_๊ทธ๋ฆ ๋ณ์์๋ input DOM ์๋ฆฌ๋จผํธ์ ์ฃผ์๊ฐ ๋ด๊น๋๋ค. */}
{/* ํฅํ ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ input DOM ์๋ฆฌ๋จผํธ๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค. */}
</div>);
์ด ์ฃผ์๊ฐ์ ์ปดํฌ๋ํธ๊ฐ re-render ๋๋๋ผ๋ ๋ฐ๋์ง ์๋
์ด ํน์ฑ์ ํ์ฉํ์ฌ ์๋์ ์ ํ๋ ์ํฉ์์ useRef ๋ฅผ ํ์ฉ ํ ์ ์๋ค.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>);
}
useRef()๋ฅผ ์ฌ์ฉํ์ฌ Ref ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ , ์ด ๊ฐ์ฒด๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ ํํ๊ณ ์ถ์ DOM ์ ref๊ฐ์ผ๋ก ์ค์ ํด์ฃผ์ด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด, Ref ๊ฐ์ฒด์ .current ๊ฐ ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ DOM ์ ๊ฐ๋ฅดํค๊ฒ ๋ฉ๋๋ค.
'Code๊ฐ๋ฐ์ผ์ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] Props Drilling + Cmarket Hooks (0) | 2022.12.27 |
---|---|
[React] React Custom Component (0) | 2022.12.26 |
[Figma] ๋จ์ถํค,, ๋น๊ทผ๋ง์ผ ์ฑ lo-fi clone (0) | 2022.12.21 |
UI UX (0) | 2022.12.19 |
JSON.stringify() // JSON.parse() // Tree UI (0) | 2022.12.16 |