
์ค๋์ React์์ Typescript ์ง์์ ์ํด ์์ฒด์ ์ผ๋ก ์ ์ํ ํ์ ์ ๋ํด์ ์์๋ณผ ์ฐจ๋ก์ด๋ค.
= Functional Component
React + Typescript ์กฐํฉ์ผ๋ก ๊ฐ๋ฐํ ๋ ์ฌ์ฉํ๋ ํ์
ํจ์ํ ์ปดํฌ๋ํธ ์ฌ์ฉ ์ ํ์ ์ ์ธ์ ์ธ ์ ์๋๋ก react์์ ์ ๊ณตํ๋ ํ์
React.FC ๋ฅผ ์ฌ์ฉํ๋ฉด props ์ ๊ธฐ๋ณธ์ ์ผ๋ก children์ด ๋ค์ด๊ฐ๋ค.
interface TestFC {
name : string,
age: number
}
const TestReactFC : React.FC<TestFC> = ({name, age})=> {
return (
<>
<h4>ReactFC ์ปดํฌ๋ํธ์
๋๋น</h4>
<p>์๋
ํ์ธ์ ์ ๋ {name} ์ด๊ณ {age} ์ด ์
๋๋น </p>
</>
)
}
export default TestReactFC
์์ React.FC ๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด๋ณด์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๊ฑธ ๋ฉ์ธํ์ด์ง์์ ๋ถ๋ฌ์ฌ ์ฐจ๋ก์ด๋ค.
//mainpage์์ ๋ถ๋ฌ์๋ณด์
import TestReactFC from "../task4/reactFC"
const MainPage = ()=>{
return (
<>
<div>
<h2>React.FC ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestReactFC name= "wendy" age={26}/>
</div>
</>
)
}
export default MainPage
๊ทธ๋ฐ๋ฐ React.FC๋ React ๋ฒ์ 18 ์ด์ ๊น์ง ์ฌ์ฉํ๋๊ฑธ ์ง์ ํ๋ค๊ณ ํ๋ค.
๊ทธ ์ด์ ๋ฅผ ๊ฐ๋จํ ์์๋ดค๋๋ฐ,,
React.FC๋ props๊ฐ ๋น ๊ฐ์ฒด๋ผ๋ ํ์๋ก ๋๊ฒจ์ ธ์ผํ๋ค๋ ์ ์ฝ์ด ์์๋ค๊ณ ํ๋ค.React.FC ๋ ์๋์ผ๋ก children ์์ฑ์ด ํฌํจ๋๋๋ฐ, React 18 ๋ฒ์ ์ด์ ์๋ JSX ์์๋ฅผ ๊ฐ์ ๋ก ๋ฐํํด์ผํ๋ค.= react ์ปดํฌ๋ํธ๋ฅผ ์ ์ํ๋ ํ์ ์ค ํ๋
falsy ํ ๊ฐ์ ๋ฆฌํดํ๋ฉด ์๋ฌด๊ฒ๋ ๋ ๋๋ง ํ์ง ์๋๋ค.import { ReactNode } from "react";
import styled from "styled-components";
const Box = styled.div`
background-color: #000;
color: #fff;
`;
interface ReactNodee {
children: ReactNode;
}
const TestReactNode = ({ children }: ReactNodee) => {
return (
<Box>
<div>{children}</div>
</Box>
);
};
export default TestReactNode;
์ด๋ ๊ฒ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ๊ณ ๋ฉ์ธํ์ด์ง์ ๋ํ๋ด๋ณด์๋ค,
import styled from "styled-components"
import TestReactFC from "../task4/reactFC"
import TestReactNode from "../task4/reactNode"
const MainPage = ()=>{
return (
<>
<BorderBox>
<h2>React.FC ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestReactFC name= "wendy" age={26}/>
</BorderBox>
<BorderBox>
<h2>ReactNode ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestReactNode>
<p>reactnode ์ฌ์ฉ์ค์
๋๋ค</p>
</TestReactNode>
</BorderBox>
</>
)
}
export default MainPage
const BorderBox = styled.div`
border:2px solid #000;
width: 500px;
border-radius: 10px;
padding-bottom:10px;
`

ReactNode์ ๊ฐ์ ๊ฒฝ์ฐ ์์๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ธํ๊ฒ ๋์์์ง์์์ (?๋ด๊ฐ ๋ชป์ฐพ์๊ฑด๊ฐ..) ์ ๋ ๊ฒ ์ฌ์ฉํ๋๊ฒ ๋ง๋ ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค.
๋ชจ๋ ํ์ ์ ๋ฐํํ ์ ์๊ธฐ๋๋ฌธ์ ์ ๋ ๊ฒ ํน๋ณํ ํ์ ์ง์ ์์ด {children} ์ผ๋ก ๋๊ฒจ๋ ๋๋๊ฑธ๊น..?
=> ๋ง์ฝ ํ์
์ ์ง์ ํ๋ค๋ฉด ๊ทธ๋งํผ ํ์
์์ ์ฑ์ด ์ฌ๋ผ๊ฐ๊ฒ ์ง,
=> ์ ํด์ง ๋ต์ ์๋ค๊ณ ํ๋ค. ์ ๋ ๊ฒ children์ผ๋ก ๋ถ๋ฆฌํ์ฌ ์ ๋ฌํด ์ค ๊ฒ์ธ์ง, ๊ทธ๋ฅ type์ ์ง์ ํด์ ๋ถ๋ฆฌํ ๊ฒ์ธ์ง๋ฅผ ๊ณ ๋ฏผํ๋ฉด ๋๋ค.
(ex. title์ ๊ฒฝ์ฐ string์ผ๋ก๋ง ํ์
์ง์ -> ํ์
์์ ์ฑ ์ฆ๊ฐ)
string ๊ณผ number ํ์
๋ฑ ์์์ ์ธ ํ์
์ ํฌํจํ์ง ์๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์ ๋ฅผ ์์ฑํด๋ณด์
type ReactElementProps = {
children: React.ReactElement
}
const TestReactElement=({children}:ReactElementProps)=>
{
return (
<>
<div>{children}</div>
</>
)
};
export default TestReactElement
//mainpage
<BorderBox>
<h2>ReactElement ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestReactElement>
{/* reactElement ์ฌ์ฉ์ค์
๋๋ค => string ์ปดํ์ผ ์๋ฌ*/}
<p>reactElement ์ฌ์ฉ์ค์
๋๋ค</p>
</TestReactElement>
</BorderBox>
์์์ ์ธ ์์๋ฅผ ๋ฐ์ง ์๋๊ฑธ ํ์ธํด๋ณด๊ณ ์ถ์ด์ ๊ฐ์ด ์์ฑํด๋ณด์๋ค.
(์ฃผ์ ์ฒ๋ฆฌ๋ ๋ถ๋ถ์ด string์ผ๋ก ์์ฑ -> ์๋ฌ๊ฐ ๋ฌ ๋ถ๋ถ์ด๋ค.)
children์ ๋ช
์์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์ถ์๋ ์ฌ์ฉ๋๋ค.import { PropsWithChildren } from "react"
type propsWithChildren = PropsWithChildren<{
title:string,
name?:string,
age?:number
}>
const TestPropsWithChildren =
(props : propsWithChildren)=> {
const {title, name,age,children} = props
return(
<div>
<p>{title}</p>
{name && <p>Name: {name}</p>}
{age && <p>Age: {age}</p>}
{children}
</div>
)
}
export default TestPropsWithChildren
mainpage์ ์ ์ฉํด๋ณด์
//mainPage.tsx
<BorderBox>
<h2>propsWithChildren ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestPropsWithChildren
title="propsWithChildren"
name="wendy"
age={26}>
</TestPropsWithChildren>
</BorderBox>

์ฝ๋๋ฅผ ์ ์ฉํ๋ฉด ์ด๋ ๊ฒ ๋๋ค.
React.FC์์ children์ ์ ์ํด์ฃผ์ง ์์๋ ๋๋ ์๋ฌ ํด๊ฒฐ์ ์ํด ๋์จํ์
์ด๋ค.PropsWithRef๋ฅผ ์ฌ์ฉํ๋ฉด ๋ณ๋์ ํ์
์ ์ ์์ด๋ ref๋ฅผ ํฌํจํ props๋ฅผ ์ ์ธํ ์ ์๋ค.๊ทธ๋ ๋ค๋ฉด ์ด์ propsWithRef ๋ฅผ ์ฌ์ฉํด๋ณด์
import { forwardRef } from "react";
interface PropsWithRef {
text: string;
}
const TestPropsWithRef = forwardRef<HTMLDivElement, PropsWithRef>(
(props, ref) => {
return <div ref={ref}>{props.text}</div>;
}
);
export default TestPropsWithRef;
์ฐ์ ๋๋ PropsWithRef ๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ค, forwardRef ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ref๋ฅผ ๋ค๋ฃจ๋ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์๋ค.
๐ด ์ฌ๊ธฐ์ ์ ๊น!
forwardRef ํจ์๊ฐ ๋ญ์ง??
์ผ๋ฐ์ ์ผ๋ก ๋ฆฌ์กํธ์์ ref prop์ HTML Element๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ prop์ผ๋ก ์ฌ์ฉํ๋๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค.
=> ๋ฐ๋ผ์ ์ด๋ ์ฌ์ฉํด์ผํ๋ ํจ์๊ฐ ๋ฐ๋ก forwardRef ํจ์ ์ด๋ค.
const ForwardedComponent = forwardRef<RefType, PropsType>((props, ref) => { // ์ปดํฌ๋ํธ ๋ก์ง });
- RefType: ์ปดํฌ๋ํธ๊ฐ ์ ๋ฌ๋ฐ์ ref์ ํ์ .
์ฃผ๋ก DOM ์์์ ํ์- PropsType: ์ปดํฌ๋ํธ๊ฐ ์ ๋ฌ๋ฐ์ props์ ํ์ . ์ฆ, ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉํ props์ ๊ตฌ์กฐ๋ฅผ ์ ์ํจ.
-props: ์ปดํฌ๋ํธ์ ์ ๋ฌ๋ props- ref: ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ ๋ฌ๋ ref
=> ์ด ref๋ฅผ ์ปดํฌ๋ํธ ๋ด๋ถ์ DOM ์์๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ฐ๊ฒฐํ ์ ์์.๋ฐ๋ผ์ forwardRef ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ํ ์ปดํฌ๋ํธ๊ฐ ref๋ฅผ ์ง์ ์ ์ผ๋ก ๋ค๋ฃฐ ์ ์์ผ๋ฉฐ, ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ ๋ฌ๋ ref๋ฅผ ์ฌ์ฉํ์ฌ ๋ด๋ถ์ DOM ์์์ ์ ๊ทผํ ์ ์๋ค.
์ด๋ ๊ฒ ์์ฑํ ๋ค๋ฅธ ์์ ์ ๊ฐ์ด ๋ฉ์ธํ์ด์ง์์ ๋ถ๋ฌ์์ ์ฌ์ฉํด๋ดค๋ค.
const MainPage = () => {
const divRef = useRef<HTMLDivElement>(null);
const onClick = () => {
if (divRef.current) {
divRef.current.style.color = "blue";
divRef.current.style.backgroundColor = "tomato";
}
};
return(
<BorderBox>
<h2>propsWithRef ์ฌ์ฉํด๋ณด๊ธฐ</h2>
<TestPropsWithRef
ref={divRef}
text="์๋์ธ์ ์ฝ๋ฅ๋๋น" />
<button
onClick={onClick}>Button์ ๋๋ฌ๋ณด๊ฑฐ๋ผ
</button>
</BorderBox>
)
interface RefObject<T> {
readonly current: T | null;
}
=> ์ฆ current ๊ฐ์ readonly๋ก ์ค์ ํด์ค์ผ๋ก์จ ์ฐธ์กฐ๊ฐ ํ๋ฒ ์์ฑ๋๋ฉด ๊ทธ ์ดํ์ ํด๋น ์ฐธ์กฐ๋ฅผ ๋ณ๊ฒฝํ์ง ๋ชปํ๋๋ก ๊ณ ์ ์ํจ๋ค.
๋๋ ์๋์ ๊ฐ์ด ์ฌ์ฉํด๋ณด์๋ค.
import { useRef } from "react";
interface RefObjectProps {
text: string;
}
const TestRefObject: React.FC<RefObjectProps> = ({ text }) => {
const inputRef = useRef<HTMLInputElement>(null);
const handleFocus = () => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.style.color = "red";
}
};
return (
<>
<input type="text" ref={inputRef} />
<button onClick={handleFocus}>ํฌ์ปค์ฑ๋ฒํผ</button>
<p>{text}</p>
</>
);
};
export default TestRefObject;
์ด๋ current๊ฐ์ ์ง์ ์์ ํ๋ฉด ์๋ฌ๊ฐ ๋ฐํํ๋ฏ๋ก inputRef.current.value = "" ๋ก ์์ฑํ์ฌ ์์ ํ ์ ์๋ค.(์ด๋ current์ ํ์ ํ๋กํผํฐ์ด๊ธฐ๋๋ฌธ์ด๋ค)