render()
render() 메소드는 class component에서만 필수적으로 필요하다.
render() 메소드가 호출되면 this.props와 this.state를 활용해서 아래 타입 중 하나를 반환한다.
- React elements: JSX를 통해 생성된다. 그 예시로 <div />와 <MyComponent />는 React가 DOM 노드 또는 사용자가 정의한 컴포넌트를 만들도록 지시하는 React 엘리먼트이다.
- Arrays and fragments: render()를 통해서 여러 개의 element들을 반환한다.
- Portals: 별도의 DOM 하위 트리에 자식 엘리먼트를 렌더링 하게 해준다.
- String and numbers: 이 값들은 DOM 상에 텍스트 노드로서 렌더링된다.
- Booleans or null: 아무것도 렌더링하지 않는다. (대부분의 경우 return test && <Child /> 패턴을 지원하는 데에 사용된다. test는 boolean 값이다.)
render() 함수는 순수해야 한다. 즉, 컴포넌트의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환해야하며, 브라우저와 직접적으로 상호작용을 하지 않는다.
ReactNode
render() 메소드를 통해서 반환되는 값이 ReactNode이다. ReactNode는 위 반환값들을 포함한다. 즉, Class Component의 반환 값은 ReactNode이다.
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
ReactElement
JSX 문법은 React.createElement(component, props, ...children)을 사용하도록 코드가 변환된다. 함수 Component는 ReactElement를 반환한다.
ReactElement는 type과 props가 있는 객체이다.
type Key = string | number
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
아래 두 코드는 동치이다.
class Hello extends React.Component {
render() {
return <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World" />,
document.getElementById('root')
);
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
JSX.Element
JSX.Element는 props와 any type가 generic type인 ReactElement 이다. JSX는 React의 global namespace에 있기 때문에, 다양한 라이브러리들이 자체적으로 JSX를 구현하여 사용할 수 있다.
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> { }
}
}
TL;DR
Functional Component 반환 값: ReactElement.
Class Component 반환 값: ReactNode
추가 정보
함수형은 "stateless components" 이다.
interface StatelessComponent<P = {}> {
(props: P & { children?: ReactNode }, context?: any): ReactElement | null;
// ... doesn't matter
}
React.FC / React.FunctionComponent
React.FC와 함께 component를 정의하면 ReactNode type의 children을 암시적으로 가져온다. 이것은 모든 component는 children을 허용한다는 뜻이다.
참고 자료
https://reactjs.org/docs/react-component.html#render
https://reactjs.org/docs/react-api.html#createelement
https://stackoverflow.com/questions/58123398/when-to-use-jsx-element-vs-reactnode-vs-reactelement
https://stackoverflow.com/questions/53688899/typescript-and-react-children-type
https://github.com/facebook/create-react-app/pull/8177
'Tech > React' 카테고리의 다른 글
useEffect 정리 (0) | 2021.07.22 |
---|---|
[Typescript] CRA에서 http-proxy-middleware 사용법 (0) | 2021.07.14 |
react 리뷰 정리 (0) | 2021.06.15 |
React component (0) | 2021.05.29 |
선언형 프로그래밍과 명령형 프로그래밍 (0) | 2021.05.11 |
댓글