React.FC์ ๋ํ์ฌ
React.FC์ ๋ํ์ฌ
Nov 27, 2022
๋ค์ด๊ฐ๋ฉฐ
์ฒ์ React + typescript ์กฐํฉ์ ์ฌ์ฉํ์ ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ๋ง์ด ์ฌ์ฉํ์ต๋๋ค.
// Parent
type Props = {
count: number;
};
const Parent: React.FC<Props> = ({ count }) => {
return <div>Parent {count}</div>;
};
export default Parent;
// App
import Parent from "./Parent";
function App() {
return (
<div className="App">
<Parent count={10} />
</div>
);
}
export default App;
๊ฐ์๋ ์ฌ๋ฌ ์์ ์์ React.FC๋ฅผ ๋ง์ด ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ โํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ๋ React.FC๋ฅผ ์ฌ์ฉํด์ผ ๋๋๊ตฌ๋โ๋ผ๋ ์๊ฐ์ ๊ฐ๊ฒ ๋์๋๋ฐ์
์ต๊ทผ์ React.FC ์ฌ์ฉ์ ์ ํํ๋ ์ถ์ธ๋ค.๋ผ๋ ๊ธ ์ ๋ณด๊ฒ ๋์์ต๋๋ค.
๋ฌด์จ์ผ ์ธ๊ณ ๊ถ๊ธํ๋ ๋ด์ฉ์ ์ฝ์ด๋ณด๋ฉด์ ์์๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด๊ฒ ์ต๋๋ค.
๊ฐ ๋ด์ฉ ์ ๋ชฉ์ ์ ๊ฐ ์ง์ญ์ ํด์ ์ด์ํ ์ ์์ผ๋ ์ํด ๋ถํ๋๋ฆฝ๋๋ค.
์ผ๋ฐ ํจ์์ ๋ค๋ฅธ ์
1. React.FunctionComponentย is explicit about the return type, while the normal function version is implicit (or else needs additional annotation).
React.FunctionComponent๋ ๋ช ์์ ์ด๋ค. ๋ฐํํ๋ type์ ๋ํด์. ๋ฐ๋ฉด์ ์ผ๋ฐ ํจ์ ๋ฒ์ ์ ์์์ ์ด๋ค ํน์ ์ถ๊ฐ๋ก annotation(ํ์ ์ง์ )์ด ํ์ํ๋ค.
*annotation์ด ํ์ํ๋ค.
React.FunctionComponent๊ฐ ๋ช ์์ ์ด๋ ๋ง์ด ๋ฌด์จ ๋ป์ผ๊น์? vscode๋ฅผ ์ผ๊ณ React.FC์ ์ด๋ค ํ์ ์ด ์ง์ ๋์ด ์๋์ง ๋ค์ด๊ฐ ๋ดค์ต๋๋ค.
type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}
@types/react์ React.FC์ 5๊ฐ์ง type์ด ์ ์๋์ด ์์ต๋๋ค.
2. It provides typechecking and autocomplete for static properties likeย โdisplayNameโ,ย โpropTypesโ, andย โdefaultPropsโ.
displayName๊ณผ propTypes ๊ทธ๋ฆฌ๊ณ defaultProps์ ๊ฐ์ ์ ์ ํ๋กํผํฐ๋ฅผ ์ํ ์๋์์ฑ๊ณผ typechecking์ ์ ๊ณตํฉ๋๋ค.
์ด prop๋ค์ด ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง ํ๋ฒ ์์๋ด ์๋ค.
1. displayName
type Props = {
count: number;
};
const Parent: React.FC<Props> = ({ count }) => {
return <div>Parent {count}</div>;
};
Parent.displayName = "Hello World";
export default Parent;
display๋ ๋ฌธ์์์ ์ฝ๊ฒ ์ฐพ์ ์ ์์๋๋ฐ์ React.Component โ React ์ผ๋ฐ์ ์ผ๋ก ๋ช ์์ ์ผ๋ก ์ฌ์ฉํ ํ์๋ ์์ง๋ง ๋๋ฒ๊น ์ฉ์ผ๋ก ์ฌ์ฉ๋๋ค๊ณ ํฉ๋๋ค.
2. propTypes, defaultProps
Typechecking With PropTypes โ ReactpropTypes์ defaultProps๋ ๋ฌธ์์ ์น์ ํ๊ฒ ์ค๋ช ๋์ด ์๋๋ฐ defaultProps๋ ์ปดํฌ๋ํธ ๊ธฐ๋ณธ๊ฐ์ ์ ์ํ๋ค๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค. ๊ณต์ ๋ฌธ์ ์์ ๋ ํด๋์ค ํ์ผ๋ก ๋์ด์์ง๋ง ํจ์ํ์ผ๋ก ํ๋ฉด ์ด๋ ๊ฒ ํํํ ์ ์์ต๋๋ค.
๊ฐ์ฒด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉ
type Props = {
count: number;
myName?: string;
};
const Parent = ({ count, myName = "hyunki" }: Props) => {
return (
<div>
Parent {myName} {count}
</div>
);
};
์ด๋ฐ defaultProps๊ฐ React.FC์์ ๋ฌธ์ ๊ฐ ๋๋ค๊ณ ํฉ๋๋ค. ์ ๊ทธ๋ฐ์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ ๋ ์ ๊ฐ ๋ง๋ ์์ ๋ก ์กฐ๊ธ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
React.FC๋ก ์ ์ํ์ง ์์
type Props = {
count: number;
// ์ ์์ ์์๋ optional๋ก ์ฃผ์์ง๋ง defaultProps๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ์ญ์ ํ์ต๋๋ค.
myName: string;
};
const Parent = ({ count, myName }: Props) => {
return (
<div>
Parent {myName} {count}
</div>
);
};
Parent.defaultProps = {
myName: "hyunki",
};
export default Parent;
// App
import Parent from "./Parent";
function App() {
return (
<div className="App">
// ์๋ฌ์์ด ํธ์ํจ..
<Parent count={10} />
</div>
);
}
export default App;
React.FC๋ก ์ ์
// Parent
type Props = {
count: number;
myName: string;
};
const Parent: React.FC<Props> = ({ count, myName }) => {
return (
<div>
Parent {myName} {count}
</div>
);
};
Parent.defaultProps = {
myName: "hyunki",
};
// App
import Parent from "./Parent";
function App() {
return (
<div className="App">
// myName ์์ฑ์ด ์๋ค๊ณ ์๋ฌ...
<Parent count={10} />
</div>
);
}
export default App;
์ ๋๋ก ๋์ํ์ง ์๋๊ฑธ ํ์ธํ ์ ์์ต๋๋ค. ๋ธ๋ก๊ทธ๋ ํธ์ํฐ์์๋ hooks์ ๋ฑ์ฅ,
์ด์ ๋ฐ๋ฅธ ํจ์ํ ์ปดํฌ๋ํธ์ ์ฌ์ฉ ๋ฑ์ผ๋ก ์ธํ์ฌ ์ ๊ฐ ์ฒ์์ ์์ฑํ ๊ฐ์ฒด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉ ์ ๊ถ์ฅํ๋ค๊ณ ํฉ๋๋ค.
3. Before theย React 18 type updates,ย โReact.FunctionComponentโ provided an implicit definition ofย โchildrenโย (see below), which was heavily debated and is one of the reasonsย
React18 type ์ ๋ฐ์ดํธ์ ์๋ React.FunctionComponent๋ children์ ์ ์๋ฅผ ์์์ ์ผ๋ก ์ ๊ณต ํ์๋๋ฐ ์ด๋ ๋ ผ๋์ด ๋ง์์ผ๋ฉฐ React.FC๊ฐ CRA(create-react-app) Typescript์์ ํ ํ๋ฆฟ์์ ์ญ์ ๋ ์ด์ ์ค ํ๋์ ๋๋ค.
children์ ์์์ ์ผ๋ก ์ ๊ณตํ๋ค..? ์์์ ์ ํฌ๊ฐ ์ดํด๋ณธ React.FC type์๋ children์ ์์๋๋ฐ ์ด๋ฐ children์ ์์์ ์ผ๋ก ์ ๊ณตํ๋ค๋ ๋ป์ผ๊น์? ์ฝ๋๋ก ํ์ธํด๋ด ์๋ค.
React 18 ๋ฒ์ ์์๋ type์ค๋ฅ๊ฐ ๋ฉ๋๋ค.
// Parent
type Props = {
count: number;
myName?: string;
};
const Parent: React.FC<Props> = ({ count, myName }) => {
return (
<div>
Parent {myName} {count}
</div>
);
};
export default Parent;
// App
import Parent from "./Parent";
function App() {
return (
<div className="App">
// IntrinsicAttributes & Props' ํ์์ 'children' ์์ฑ์ด ์์ต๋๋ค
<Parent count={10}>
<p>๋๋ children ์
๋๋ค.</p>
</Parent>
</div>
);
}
export default App;
ํ์ง๋ง React17์์๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ณ ๊ทธ๋ฅ ๋์ด๊ฐ๋๋ค. ์ค๋ฅ๋ฅผ ์ค์ด๊ธฐ ์ํด typescript๋ฅผ ๋์ ํ๋ ์ ์ฅ์์ ์ด๋ฐ ์ด์๋ ์กฐ๊ธ ํฌ๋ฆฌํฐ์ปฌ ํ ๊ฒ ๊ฐ์ต๋๋ค.
๋ง์น๋ฉฐ
์ง๊ธ๊น์ง React.FC ์ฌ์ฉ ์ ํ์ด๋ผ๋ ๋ด์ฉ์ ์ดํด๋ดค์ต๋๋ค. ๋ง์ ์ฌ๋๋ค์ด ์ฌ์ฉํ๊ธฐ์ ์ผ๋ฐ์ ์ผ๋ก ์ฐ์ด๋์ค ์์๊ณ ๋ง์ด ์ฐ๋ React.FC์ ๋ํ ๋ฐฐ์ ๊ฐ(?)๋ ๋ค๋ฉด์ ํํธ์ผ๋ก๋ ๊น๊ฒ React๋ฅผ ์ฌ์ฉ ํด๋ดค๋ค๋ฉด ์ถฉ๋ถํ ์ฒด๊ฐํ ์ ์์๋ ์ด์์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.