Skip to main content

Basic Snippets

ComponentReference vs ComponentInstance

import React from "react";
import { render } from "react-dom";

const MyComponent = () => <div>Hello, World!</div>;

// 예시 1: {Component} 사용
const AppWithComponentReference = ({
Component,
}: {
Component: React.ReactNode;
}) => (
<div>
<h1>Using Component Reference</h1>
{Component} {/* 단순히 컴포넌트 타입을 삽입 */}
</div>
);

// 예시 2: <Component /> 사용
const AppWithComponentInstance = ({
Component,
}: {
Component: React.ComponentType; // () => React.ReactElement;
}) => (
<div>
<h1>Using Component Instance</h1>
<Component /> {/* 실제로 컴포넌트를 렌더링 */}
</div>
);
// 실제 렌더링
export const Test01 = () => {
return (
<>
<div>
<AppWithComponentReference Component={<MyComponent />} />
<AppWithComponentInstance Component={MyComponent} />
</div>
</>
);
};

1.
만약에 컴포넌트와 엘리먼트를 헷갈려서 잘못 쓴다면 아래와 같은 메시지를 보게된다.
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

2.
컴포넌트는 React.Element를 리턴하는 함수이다.
const component = ()=> <h1>Hello, World!</h1>;
엘리먼트는 함수가 아니다. 불변하는 JSX 그 자체이다.
const element = <h1>Hello, World!</h1>;

3.
children 처럼 특별한 props는 리액트 Element 뿐 아니라 다른 유형도 가능.
- 그래서 React.ReactNode 로 타이핑 한다.
- React 요소뿐만 아니라 문자열, 숫자, null, undefined, 배열 등 다양한 유형의 값들을 포함
- React.Element<></>JSX의 결과물이다.

Namespace Pattern, Slot Pattern

import React from 'react';
import styled from '@emotion/styled';

export const DesktopDetailLayoutSlot = ({
LeftComponent,
RightComponent,
}: {
LeftComponent: React.ReactNode;
RightComponent: React.ReactNode;
}) => {
return (
<div>
<Wrapper>
<LeftContentWrapper>{LeftComponent}</LeftContentWrapper>
<RightContentWrapper>{RightComponent}</RightContentWrapper>
</Wrapper>
</div>
);
};

const Wrapper = styled.div`
display: flex;
width: 100%;
justify-content: center;
padding: 40px 0;
`;

const LeftContentWrapper = styled.div`
display: flex;
flex-direction: column;
width: 50%;
max-width: 512px;
height: calc(100vh - 71px);
padding: 40px 40px 40px 0;
`;

const RightContentWrapper = styled.div`
display: flex;
width: 50%;
max-width: 512px;
height: calc(100vh - 71px);
`;

export const DesktopDetailLayout = {
Wrapper: React.forwardRef((props: any, ref) => (
<Wrapper align="center" justify="center" {...props} ref={ref} />
)),
LeftContentWrapper: React.forwardRef((props: any, ref) => (
<LeftContentWrapper align="center" {...props} ref={ref} />
)),
RightContentWrapper: React.forwardRef((props: any, ref) => (
<RightContentWrapper justify="center" {...props} ref={ref} />
)),
};