이 시리즈에서는 React와 기능적으로 유사한 작은 프런트엔드 프레임워크를 구축하여 React가 내부적으로 어떻게 작동하는지 설명합니다. 이 장에서는 JSX를 다룹니다.
Bun을 런타임으로 사용하겠습니다. 노드에는 TypeScript 및 컴파일을 위한 추가 구성이 필요할 수 있습니다.
이 튜토리얼은 이 튜토리얼을 기반으로 하지만 JSX, TypeScript 및 구현하기 더 쉬운 접근 방식을 사용합니다. 내 GitHub 저장소에서 메모와 코드를 확인할 수 있습니다.
자, 더 깊이 들어가기 전에 먼저 React-jsx의 몇 가지 중요한 요소를 살펴보겠습니다.
React 구성 요소의 트랜스파일된 코드를 살펴보면 이것이 단지 함수 호출 묶음이라는 것을 알 수 있습니다. JSX는 React.createElement의 구문 설탕일 뿐입니다. 즉, 예를 들어 다음 JSX 코드는 다음과 같습니다.
const element = <h1 className="greeting">Hello, world!</h1>;
다음으로 변환됩니다:
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
React.createElement는 또 다른 핵심 메커니즘인 가상 요소를 생성합니다. 간단히 말해서 가상 요소는 가상 DOM의 요소입니다. 가상 DOM은 실제 DOM을 나타내는 것입니다. 가상 DOM에서 작업하는 것은 단순히 js 객체를 작업하는 것이므로 실제 DOM에서 작업하는 것보다 훨씬 빠릅니다. 다음 장에서는 가상 DOM에 대해 이야기하겠습니다. 하지만 지금은 JSX가 React.createElement의 구문 설탕이라는 것을 아는 것만으로도 충분합니다.
React.createElement 함수는 다음 인수를 순서대로 사용합니다.
쉬운 일인 것 같죠? 그럼 해보자.
컴파일할 때 사용할 함수를 지정할 수 있습니다. 기본적으로 함수는 React.createElement입니다. 하지만 우리만의 기능을 사용할 수도 있습니다.
그래서 가상 요소를 먼저 정의하기 위해 v-dom.ts를 생성합니다.
export type VDomAttributes = { key?: string | number [_: string]: string | number | boolean | Function | undefined } export interface VDomElement { kind: 'element' tag: string children?: VDomNode[] props?: VDomAttributes key: string | number | undefined } export type VDomNode = | string | VDomElement
각 노드에는 키 필드가 있습니다(노드는 텍스트나 요소의 이름일 뿐입니다). 이는 화해를 위한 것이며, 이에 대해서는 다음 장에서 다루겠습니다. 지금은 무시해도 됩니다.
이제 createElement 함수를 구현할 수 있습니다. 같은 파일에 넣었습니다.
export function createElement(tag: string, props: VDomAttributes, ...children: VDomNode[]): VDomElement { console.log('createElement', tag, props, children) return { kind: 'element', tag, children, props, key: props?.key ?? undefined } }
이제 컴파일러에게 이 함수를 사용하도록 지시합니다. 파일 상단에 다음 줄을 추가하면 됩니다.
const element = <h1 className="greeting">Hello, world!</h1>;
React 표준을 채택하고 있으므로 React 유형 정의를 도입해야 합니다. 파일 상단에 다음 줄을 추가하면 됩니다.
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
그런 다음 tsconfig.json에서compileOptions 필드에 다음 줄을 추가합니다.
export type VDomAttributes = { key?: string | number [_: string]: string | number | boolean | Function | undefined } export interface VDomElement { kind: 'element' tag: string children?: VDomNode[] props?: VDomAttributes key: string | number | undefined } export type VDomNode = | string | VDomElement
이제 우리가 만든 가상 요소를 살펴보겠습니다.
export function createElement(tag: string, props: VDomAttributes, ...children: VDomNode[]): VDomElement { console.log('createElement', tag, props, children) return { kind: 'element', tag, children, props, key: props?.key ?? undefined } }
JSX 코드를 기반으로 정의된 가상 돔 요소만 표시됩니다.
또한 공식 이름을 모르는 경우 조각 요소인 <>>를 정의할 수도 있습니다. 파일 상단에 다음 줄을 추가하면 됩니다.
조각을 처리할 때 컴파일러는 구성된 조각 팩토리를 요소 생성 함수의 태그로 가져옵니다. 이는 기능적 구성 요소가 작동하는 방식과 동일합니다. 기능적 구성 요소는 다음 장에서 설명할 기능을 태그에 적용합니다.
그럼에도 불구하고 우리 구현에서는 복잡한 처리가 필요하지 않습니다. 단지 조각에 대한 특수 태그를 설정하기만 하면 됩니다.
import { createElement as h } from './v-dom'
추가 컴파일러 옵션
bun i @types/react
기본적으로 프래그먼트는 빈 태그가 있는 특수 요소일 뿐입니다. 프래그먼트 생성 시 컴파일러는 jsxFragmentFactory를 가져와 createElement의 첫 번째 매개변수에 있는 태그 매개변수에 넣습니다. 따라서 다른 요소와 조각을 쉽게 구분할 수 있습니다.
"compilerOptions": { "jsx": "react", "jsxFactory": "createElement", }
이 코드는 가상 DOM을 수정합니다. 지금까지 우리는 작은 React의 JSX 부분을 구현했습니다.
아, 3장의 저자입니다. 실제로 현재 JSX 구현은 완벽하지 않습니다. 세 번째 장에서 이를 수정하겠습니다. 이제는 다음과 같은 구문을 지원하지 않습니다.
import { createElement } from "./v-dom"; function App() { return <div> <h1>a</h1> <h2>b</h2> </div> } console.log(App());
이는 모든 {}가 하나의 하위 항목으로 처리되고 지도가 배열을 반환하기 때문입니다. 따라서 중첩된 하위 항목을 가지게 됩니다.
또한 다음 장에서 설명할 기능적 구성 요소를 아직 지원하지 않았습니다.
현재 버전을 따르고 나중에 수정하면 됩니다. 불편을 드려 죄송합니다.
위 내용은 작은 React ChSX 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!