๐์ค๋ ๋ฐฐ์ด ๊ฒ
<React>
Portals
: ๋ถ๋ชจ ์ปดํฌ๋ํธ์ DOM ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ๊นฅ์ ์๋ DOM ๋ ธ๋๋ก ์์์ ๋ ๋๋ง ํ๋ ๋ฐฉ๋ฒ
์ฒซ ๋ฒ์งธ ์ธ์๋ ๋ ๋๋ง ํ ์ ์๋ React ์์์, ๋๋ฒ์งธ ์ธ์๋ก๋ ์์์ ๋ ๋๋งํ DOM์๋ฆฌ๋จผํธ๋ฅผ ๋ฐ๋๋ค.
const el = useMemo(() => document.createElement("div"), []);
useEffect(() => {
document.body.appendChild(el);
return () => {
document.body.removeChild(el);
};
});
return ReactDOM.createPortal(
<BackgroundDim style={{ display: visible ? "block" : "none" }}>
<ModalContainer
ref={ref}
{...props}
style={{ ...props.style, ...containerStyle }}
>
{children}
</ModalContainer>
</BackgroundDim>
);
useReducer
: ์ปดํฌ๋ํธ์ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ์ปดํฌ๋ํธ์์ ๋ถ๋ฆฌ์ํฌ ์ ์๋ค.
reducer๋ ํ์ฌ ์ํ์ ์ก์ ๊ฐ์ฒด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ ์๋ก์ด ์ํ๋ก ๋ฐํํ๋ค. ์ฆ, reduce์์ ๋ฐํํ๋ ์ํ๊ฐ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ง ์๋ก์ด ์ํ์ธ ๊ฒ.
const [state, dispatch] = useReducer(reducer, initialState);
state๋ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ํ์ด๊ณ dispatch๋ ์ก์ ์ ๋ฐ์์ํค๋ ํจ์์ด๋ค.
์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ reducerํจ์์ด๊ณ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ์ด๊ธฐ๊ฐ์ด๋ค.
์ฌ์ฉ์์
const reducer = (state, action) => {
switch (action.type) {
case "INIT_POSTS": {
console.log(action);
return action.payload;
}
case "ADD_POST": {
return [...state, action.payload.response.data];
}
case "DELETE_POST": {
const payload = action.payload;
return state.filter((item) => item.id !== payload.id);
}
default: {
console.error("Wrong Type");
break;
}
}
};
ํด๋นํ๋ case์ ๋ฐ๋ผ return์ ํ๊ฒ ๋๋ค.
ํธ์ถํ ๋
dispatch({ type: "ADD_POST", payload });
์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ํธ์ถํ ์ ์๋ค.
<css >
first-child๋ first-of-type ์ฐจ์ด์
firsst-child : ์์ ์์ ์ค์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ๋ฅผ ์ ํ
first-of-type: ์์ ์์ ์ค์ ํด๋น ํ์ ์ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ๋ฅผ ์ ํ, ํน์ ํ์ ์๋ฆฌ๋จผํธ์ ๋ํด์ ์นด์ดํธ๋ฅผ ํ๋ค.
<div>
<h1>div</h1>
<p>p1</p>
<p>p2</p>
</div>
์์ ์์์์ p1์ ๊ธ์ ์์ ํ๋์์ผ๋ก ๋ฐ๊ฟ๋ณด์.
/* 1*/
div p:first-child {
color: blue;
}
/* 2 */
div p:first-of-type {
color: blue;
}
1์์๋ first-child๋ฅผ 2์์๋ first-of-type์ ์ฌ์ฉํ๋๋ฐ 1์ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์๊ณ 2๋ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
์๋ํ๋ฉด first-child๋ div ํ์์ p์๋ฆฌ๋จผํธ๊ฐ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ์ ์์นํด์ผ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ํ์ง๋ง ์์ ์์์์ ์ฒซ ๋ฒ์งธ ์๋ฆฌ๋จผํธ๋ div์ด๊ธฐ ๋๋ฌธ์ ์ํ๋ ๋๋ก ์๋ํ์ง ์์ ๊ฒ์ด๋ค.
๋ฐ๋ฉด first-of-type์ ๊ฒฝ์ฐ p์๋ฆฌ๋จผํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์นด์ดํธํ๊ธฐ ๋๋ฌธ์ ์ํ๋ ๋๋ก ์๋ํ๋ค. ์ฆ, first-child๋ ํ์ ์ ๊ด๊ณ์์ด ์ฒซ๋ฒ์งธ์ ์์นํด์ผ ์ํ๋ ๋๋ก ์๋ํ๊ณ first-of-type์ ์์น์ ๊ด๊ณ์์ด ํ์ ์ ๊ธฐ์ค์ผ๋ก ์ฒดํฌํด์ ์นด์ดํธ๋ฅผ ํ๋ค.
(๋ง์ฝ div h1:first-child ๋ผ๋ฉด ์๋ํ๋๋ก ์๋ํ๊ฒ ๋๋ค!)
<HTML>
canvas
:html ๋ฌธ์ ๋ด๋ถ์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆด ์ ์๋ ์๋ฆฌ๋จผํธ
- getContext: ๋ ๋๋ง ์ปจํ ์คํธ ํ์ ์ ์ง์ ํ๋ค.
canvas.getContext('2d');
- beginPath(): ์ ์ ๊ทธ๋ฆฌ๊ธฐ ์์ํจ์ ์ง์
- closePath(): ์ ์ ๋ซ์์ ์์์ ๊ณผ ๋ ์ ์ ์๋๋ค.
- moveTo(): ์ ์ ๊ทธ๋ฆฌ์ง ์๊ณ ์ขํ๋ฅผ ์ด๋
- stroke(): ์ค๊ณฝ์ ์ ์คํ์ผ์ ์ง์
- linTo(x, y)(): ํ์ฌ ์์น์์ ์ง์ ํ ์์น๊น์ง ์ ์ ๊ทธ๋ฆฐ๋ค.
- ...
์ด์ธ์๋ ๋ค์ํ ํจ์๊ฐ ์กด์ฌํ๋ค.
<JavaScript>
Object.assign
:๊ฐ์ฒด๋ค์ ๋ชจ๋ ์ด๊ฑฐ ๊ฐ๋ฅํ ์์ฑ์ ๋ณต์ฌํด์ ๋์ ๊ฐ์ฒด์ ๋ถ์ฌ๋ฃ๋๋ค.
Object.assign(target, ...sources)
target: ๋ชฉํ๊ฐ์ฒด - ์ถ์ฒ ๊ฐ์ฒด์ ์์ฑ์ ๋ณต์ฌํด ๋ฐ์ ํ ๋ฐํํ ๊ฐ์ฒด์ด๋ค.
sources: ์ถ์ฒ ๊ฐ์ฒด - ๋ชฉํ ๊ฐ์ฒด๊ฐ ๋ฐ์ํ๊ณ ์ ํ๋ ์์ฑ๋ค์ ๊ฐ์ง ๊ฐ์ฒด
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target);
// expected output: true
๐ญ๋๋ ์
์ด๋ ต๋ค! ๋ก์ง๋ ์ด๋ ต๊ณ ... ๋ด๊ฐ ์๋ ๋ฆฌ์กํธ์ธ๋ฐ ๋ด๊ฐ ์๋ ๋ฆฌ์กํธ๊ฐ ์๋์ผ.. ์ข ๋ง์ด ์ฌ์ฉํด๋ณด๊ณ ๋ฏ์ด๋ณด๊ณ ํด์ผ ์ดํด๋ ๊ฒ ๊ฐ๋ค. ์ค๋ ์์ธ์ง ์ธ๋ด์ฌ ๋ฐ๋ฅ์ด์ด์ ์ค๋ฅ๋ ๋๋ง๋ค ์ฑ ์์ ๋ช ๋ฒ์ ๋ด๋ ค์ณค๋์ง... ์ค๋ ๋ง์ด ๋ชปํ ๋ถ๋ถ์ ๋ด์ผ ๊ผญ ๋คํด์ ๋ ์ด์ ์ ๋ฐ๋ ค์ผ์ง.. ๋ด์ผ์ ํ๋ด์!!!
'์ผ์ > Today I Learned' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ฐ๋ธ์ฝ์ค Day53] 2022.12.28 (0) | 2022.12.28 |
---|---|
[๋ฐ๋ธ์ฝ์ค Day52] 2022.12.27 (0) | 2022.12.27 |
[๋ฐ๋ธ์ฝ์ค Day 50] 2022.12.23 (0) | 2022.12.23 |
[๋ฐ๋ธ์ฝ์ค Day49] 2022.12.22 (0) | 2022.12.22 |
[๋ฐ๋ธ์ฝ์ค Day 48] 2022.12.21 (0) | 2022.12.21 |
๐์ค๋ ๋ฐฐ์ด ๊ฒ
<React>
Portals
: ๋ถ๋ชจ ์ปดํฌ๋ํธ์ DOM ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ๊นฅ์ ์๋ DOM ๋ ธ๋๋ก ์์์ ๋ ๋๋ง ํ๋ ๋ฐฉ๋ฒ
์ฒซ ๋ฒ์งธ ์ธ์๋ ๋ ๋๋ง ํ ์ ์๋ React ์์์, ๋๋ฒ์งธ ์ธ์๋ก๋ ์์์ ๋ ๋๋งํ DOM์๋ฆฌ๋จผํธ๋ฅผ ๋ฐ๋๋ค.
const el = useMemo(() => document.createElement("div"), []);
useEffect(() => {
document.body.appendChild(el);
return () => {
document.body.removeChild(el);
};
});
return ReactDOM.createPortal(
<BackgroundDim style={{ display: visible ? "block" : "none" }}>
<ModalContainer
ref={ref}
{...props}
style={{ ...props.style, ...containerStyle }}
>
{children}
</ModalContainer>
</BackgroundDim>
);
useReducer
: ์ปดํฌ๋ํธ์ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ์ปดํฌ๋ํธ์์ ๋ถ๋ฆฌ์ํฌ ์ ์๋ค.
reducer๋ ํ์ฌ ์ํ์ ์ก์ ๊ฐ์ฒด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ ์๋ก์ด ์ํ๋ก ๋ฐํํ๋ค. ์ฆ, reduce์์ ๋ฐํํ๋ ์ํ๊ฐ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ง ์๋ก์ด ์ํ์ธ ๊ฒ.
const [state, dispatch] = useReducer(reducer, initialState);
state๋ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ํ์ด๊ณ dispatch๋ ์ก์ ์ ๋ฐ์์ํค๋ ํจ์์ด๋ค.
์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ reducerํจ์์ด๊ณ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ์ด๊ธฐ๊ฐ์ด๋ค.
์ฌ์ฉ์์
const reducer = (state, action) => {
switch (action.type) {
case "INIT_POSTS": {
console.log(action);
return action.payload;
}
case "ADD_POST": {
return [...state, action.payload.response.data];
}
case "DELETE_POST": {
const payload = action.payload;
return state.filter((item) => item.id !== payload.id);
}
default: {
console.error("Wrong Type");
break;
}
}
};
ํด๋นํ๋ case์ ๋ฐ๋ผ return์ ํ๊ฒ ๋๋ค.
ํธ์ถํ ๋
dispatch({ type: "ADD_POST", payload });
์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ํธ์ถํ ์ ์๋ค.
<css >
first-child๋ first-of-type ์ฐจ์ด์
firsst-child : ์์ ์์ ์ค์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ๋ฅผ ์ ํ
first-of-type: ์์ ์์ ์ค์ ํด๋น ํ์ ์ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ๋ฅผ ์ ํ, ํน์ ํ์ ์๋ฆฌ๋จผํธ์ ๋ํด์ ์นด์ดํธ๋ฅผ ํ๋ค.
<div>
<h1>div</h1>
<p>p1</p>
<p>p2</p>
</div>
์์ ์์์์ p1์ ๊ธ์ ์์ ํ๋์์ผ๋ก ๋ฐ๊ฟ๋ณด์.
/* 1*/
div p:first-child {
color: blue;
}
/* 2 */
div p:first-of-type {
color: blue;
}
1์์๋ first-child๋ฅผ 2์์๋ first-of-type์ ์ฌ์ฉํ๋๋ฐ 1์ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์๊ณ 2๋ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
์๋ํ๋ฉด first-child๋ div ํ์์ p์๋ฆฌ๋จผํธ๊ฐ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ์ ์์นํด์ผ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ํ์ง๋ง ์์ ์์์์ ์ฒซ ๋ฒ์งธ ์๋ฆฌ๋จผํธ๋ div์ด๊ธฐ ๋๋ฌธ์ ์ํ๋ ๋๋ก ์๋ํ์ง ์์ ๊ฒ์ด๋ค.
๋ฐ๋ฉด first-of-type์ ๊ฒฝ์ฐ p์๋ฆฌ๋จผํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์นด์ดํธํ๊ธฐ ๋๋ฌธ์ ์ํ๋ ๋๋ก ์๋ํ๋ค. ์ฆ, first-child๋ ํ์ ์ ๊ด๊ณ์์ด ์ฒซ๋ฒ์งธ์ ์์นํด์ผ ์ํ๋ ๋๋ก ์๋ํ๊ณ first-of-type์ ์์น์ ๊ด๊ณ์์ด ํ์ ์ ๊ธฐ์ค์ผ๋ก ์ฒดํฌํด์ ์นด์ดํธ๋ฅผ ํ๋ค.
(๋ง์ฝ div h1:first-child ๋ผ๋ฉด ์๋ํ๋๋ก ์๋ํ๊ฒ ๋๋ค!)
<HTML>
canvas
:html ๋ฌธ์ ๋ด๋ถ์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆด ์ ์๋ ์๋ฆฌ๋จผํธ
- getContext: ๋ ๋๋ง ์ปจํ ์คํธ ํ์ ์ ์ง์ ํ๋ค.
canvas.getContext('2d');
- beginPath(): ์ ์ ๊ทธ๋ฆฌ๊ธฐ ์์ํจ์ ์ง์
- closePath(): ์ ์ ๋ซ์์ ์์์ ๊ณผ ๋ ์ ์ ์๋๋ค.
- moveTo(): ์ ์ ๊ทธ๋ฆฌ์ง ์๊ณ ์ขํ๋ฅผ ์ด๋
- stroke(): ์ค๊ณฝ์ ์ ์คํ์ผ์ ์ง์
- linTo(x, y)(): ํ์ฌ ์์น์์ ์ง์ ํ ์์น๊น์ง ์ ์ ๊ทธ๋ฆฐ๋ค.
- ...
์ด์ธ์๋ ๋ค์ํ ํจ์๊ฐ ์กด์ฌํ๋ค.
<JavaScript>
Object.assign
:๊ฐ์ฒด๋ค์ ๋ชจ๋ ์ด๊ฑฐ ๊ฐ๋ฅํ ์์ฑ์ ๋ณต์ฌํด์ ๋์ ๊ฐ์ฒด์ ๋ถ์ฌ๋ฃ๋๋ค.
Object.assign(target, ...sources)
target: ๋ชฉํ๊ฐ์ฒด - ์ถ์ฒ ๊ฐ์ฒด์ ์์ฑ์ ๋ณต์ฌํด ๋ฐ์ ํ ๋ฐํํ ๊ฐ์ฒด์ด๋ค.
sources: ์ถ์ฒ ๊ฐ์ฒด - ๋ชฉํ ๊ฐ์ฒด๊ฐ ๋ฐ์ํ๊ณ ์ ํ๋ ์์ฑ๋ค์ ๊ฐ์ง ๊ฐ์ฒด
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target);
// expected output: true
๐ญ๋๋ ์
์ด๋ ต๋ค! ๋ก์ง๋ ์ด๋ ต๊ณ ... ๋ด๊ฐ ์๋ ๋ฆฌ์กํธ์ธ๋ฐ ๋ด๊ฐ ์๋ ๋ฆฌ์กํธ๊ฐ ์๋์ผ.. ์ข ๋ง์ด ์ฌ์ฉํด๋ณด๊ณ ๋ฏ์ด๋ณด๊ณ ํด์ผ ์ดํด๋ ๊ฒ ๊ฐ๋ค. ์ค๋ ์์ธ์ง ์ธ๋ด์ฌ ๋ฐ๋ฅ์ด์ด์ ์ค๋ฅ๋ ๋๋ง๋ค ์ฑ ์์ ๋ช ๋ฒ์ ๋ด๋ ค์ณค๋์ง... ์ค๋ ๋ง์ด ๋ชปํ ๋ถ๋ถ์ ๋ด์ผ ๊ผญ ๋คํด์ ๋ ์ด์ ์ ๋ฐ๋ ค์ผ์ง.. ๋ด์ผ์ ํ๋ด์!!!
'์ผ์ > Today I Learned' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ฐ๋ธ์ฝ์ค Day53] 2022.12.28 (0) | 2022.12.28 |
---|---|
[๋ฐ๋ธ์ฝ์ค Day52] 2022.12.27 (0) | 2022.12.27 |
[๋ฐ๋ธ์ฝ์ค Day 50] 2022.12.23 (0) | 2022.12.23 |
[๋ฐ๋ธ์ฝ์ค Day49] 2022.12.22 (0) | 2022.12.22 |
[๋ฐ๋ธ์ฝ์ค Day 48] 2022.12.21 (0) | 2022.12.21 |