제 JSX 렌더기가 뭘 가르쳐줬는지 적어주세요.
28043 단어 reacttypescriptmarkdownjavascript
React가 이렇게 유행하는 이유 중 하나는 바로 그것이 도입한 문법이다. HTML과 비슷한 코드를 작성해서 구성 요소를 성명적으로 설명하는 것이 매우 좋다.그런데 왜 이런 문법은 React에만 사용되고 기본적으로 HTML을 묘사하는 데 사용되는가?
몇 분의 연구를 통해 나는 처음으로 사실이 그렇지 않다는 것을 깨달았다. 그리고 적어도 한 명은 행동에서 보았을 것이다. Ink.그것은 게이츠비, 실 또는 지형과 같은 CLI를 성명적으로 구축하는 데 쓰인다.
이것은 나로 하여금 혼자서 비슷한 일을 시도할 용기를 가지게 했다. 이것은 jsx-readme 과 잠재적 jsx-md 으로 통하는 여정이었다.이 글에서 저는 여러분을 이끌고 제 여정과 이로 인해 일어난 JSX와 React에 대한 학습을 마치겠습니다.
만약 당신이 과학 기술, 창업, 그리고 어떻게 둘을 결합시키는지에 대한 더 많은 정보에 관심이 있다면 언제든지 우리에게 연락하십시오.
우리의 목표
저희가 이렇게 코드를 짰으면 좋겠어요.
function Readme() {
return (
<Fragment>
<Heading level={1}>{pkg.name}</Heading>
<LineBreak />
<Text>{pkg.description}</Text>
</Fragment>
);
}
writeFile("examples/README.md", <Readme />);
이렇게 가격 인하.# jsx-md
Generate markdown files with a React\-like syntax.
잠시 후, 이 구축 블록에서 더 복잡한 구성 요소를 작성할 수 있습니다.하지만 이제: 몇 가지 기본 원리부터 시작합시다.너는 네가 알고 있는 모든 것을 뛰어넘어 톱뉴스에 주목할 수 있다.값을 내리다
Markdown은 태그 언어입니다.그것은 텍스트 문자의 도움말 아래 사체나 굵은 글씨체를 추가할 수 있도록 한다.이 박문은 가격 인하법으로 쓴 것이다.
## Markdown
Markdown is a markup language. It allows to add formatting like *italics* or __bold__ with help of text characters. E. g. this blog post is written in Markdown:
이것은 또한 코드 문서, 예를 들어 자술한 파일에도 사용된다.JSX
JSX는 JavaScript의 문법 사탕이다.이것은 순수한 자바스크립트로 컴파일되기 때문에 웹 패키지나 TypeScript를 통해서만 사용할 수 있습니다.아래로 컴파일하려면 어떤 Pragma를 사용해야 하는지 알아야 합니다.기본적으로 대부분의 컴파일러는 예를 들어 React를 사용합니다.
<article>
<h1 id='primary'>Writing Markdown with JSX</h1>
<p>One of the reasons that React got so popular...</p>
</article>
되다React.createElement(
'article',
{},
React.createElement('h1', { id: 'primary' }, 'Writing Markdown with JSX'),
React.createElement('p', {}, 'One of the reasons that React got so popular...')
)
그러나 파일의 시작에pragmasomeOtherFunction
를 추가하면 컴파일러가 React.createElement
가 아닌 다른 함수/** @jsx someOtherFunction */
를 사용하도록 알려줄 수 있다.마지막으로 JSX는 함수 호출의 문법사탕일 뿐이다
첫 번째 시도: 순수한 문자열로 되돌아오기
그래서 만약에 JSX가 함수의 문법사탕이고 마크다운은 특수한 문자열일 뿐이라면 왜 문자열을 되돌려주는 함수를 작성하지 않겠는가?이것은 내가 시도한 첫 번째 방법이며, 다음과 같은 코드가 만들어졌다.
/* @jsx createElement */
function createElement (typeOrComponent, attributes, ...children): string {
if (typeof typeOrComponent === 'function') {
return typeOrComponent({ ...(attributes ?? {}), children })
}
return children.join('')
}
function Heading ({ children, level }: Props) {
return <md-text>{'#'.repeat(level)} {children}</md-text>
}
assert.strictEqual(<Heading level={1}>Test</Heading>, '# Test')
이거 aworking version에 보냈어요.그런데 왜 이 버전은 발표되지 않았을까요?발표하기 전에 문서를 추가하고 싶습니다.문서에 대해 TypeDoc를 사용하고 싶습니다. 그러면 코드를 넣고 예쁜 HTML 파일을 자동으로 만들 수 있습니다.
문제가 어디에서 발생했습니까?TypeDoc는 React를 사용하고 React 유형을 글로벌 공간으로 가져옵니다.그래서
<Heading>Test</Heading>
문자열을 되돌릴 때 TypeScript 오류가 발생했습니다.이것은 나로 하여금 두 가지 선택을 하게 한다.
에피소드: 어떻게 했어요?
React가 어떻게 이 점을 해냈는지 알아보기 위해 나는 두 가지 출처를 연구했다.
<div className='test'>Test</div>
React.createElement('div', { className: 'test' }, 'Test')
의 문법당)는 소위 원소를 되돌려준다.{
type: 'div',
props: {
children: 'Test',
className: 'test'
},
}
중첩된 도구(예: 하위 요소)의 경우 요소는 중첩된 JSON 구조가 됩니다.그런 다음 render 함수는 구조를 HTML로 변환하거나 문자열 렌더링 프로그램의 경우 HTML을 포함하는 문자열로 변환합니다.
두 번째 시도: 원소를 되돌려줍니다
이제 createElement에서 직접 가격 인하 문자열을 반환하지 않고 요소를 반환한 다음 별도의 렌더링 함수에서 요소를 렌더링합니다.
/* @jsx createElement */
function createElement (type, attributes, ...children) {
return {
type,
props: {
...(attributes ?? {}),
children: children.length <= 1 ? children[0] : children,
},
key: null,
};
}
function render(element): string {
if (element === null || element === undefined || element === false) {
return "";
}
if (typeof element === "string") {
return element;
}
if (typeof element === "number") {
return element.toString();
}
if (Array.isArray(element)) {
return element.map((el) => renderNode(el)).join("");
}
if (typeof element.type === "function") {
return render(element.type(element.props));
}
throw new Error("Invalid element");
}
function Heading ({ children, level }: Props) {
return <md-text>{'#'.repeat(level)} {children}</md-text>
}
assert.strictEqual(render(<Heading level={1}>Test</Heading>), '# Test')
Yoyu는 수정되지 않은 완전한 코드를 찾을 수 있습니다. version 1.1.0jsx md의 실제 응용
jsx md를 사용하기 시작했을 때, 나는 이미 응용 프로그램이 생각났다.내가 쓴 첫 번째 소스 항목 중 하나는 CoffeeScript의 스크립트이며 소스 항목을 위한 자술 파일을 만듭니다.jsx md가 있으면, 나는 현재 자술한 파일의 구성 요소를 성명적으로 설명할 수 있다.
import package from './package.json'
const DescriptionFromPkg: Component<Props> = ({
pkg: { description },
}: Props) => {
if (description === undefined) {
return null;
}
return (
<Fragment>
<Text>{description}</Text>
<LineBreak />
<LineBreak />
</Fragment>
);
};
writeFileSync('README.md', render(<DescriptionFromPkg pkg={package} />))
전반적으로 말하자면, 이것은 나로 하여금 쓰기 시작하게 한다. jsx-readme 이것은 JSX로 자술한 파일을 설명하는 라이브러리이다.그런데 갈고리는요?
현재, 리액션을 쓰는 것은 심지어 훅스를 한 번도 언급하지 않는 것은 매우 드물다.그럼 갈고리는요?
연결고리는 React가 두 가지 문제를 해결하는 해결 방안이다. 첫째, 구성 요소의 성명성 설명은 렌더링할 때마다 실행되지만, 일부 부작용은 실행되지 말아야 한다. 둘째, 하나의 구성 요소가 새로운 데이터를 사용하여 다시 렌더링할 수 있도록 알려주고, 완전한 구성 요소 트리를 통해 이 정보를 전달할 필요가 없다.
이 두 가지 방법은 모두 정적 태그 파일을 렌더링하는 것과 무관합니다. 이것은 실제로 부작용이 없고, 렌더링 기능이 연속적으로 실행될 수 없을 정도로 시간이 너무 깁니다.그러나 jsx 자술 파일을 처리할 때, 나는 확실히 React의 갈고리로 해결할 수 있는 문제를 만났고, 나는 jsx md로 이러한 문제를 해결할 수 없었다.
구성 요소에 필요한 데이터를 먼저 보여주려면 비동기적으로 가져와야 합니다. 어떻게 해야 합니까?
다행히도 갈고리를 완전히 실현할 필요는 없고 상하문도 필요 없다.반대로 내가 해야 할 일은 렌더링을 비동기적으로 하고 요소의 하위 요소로 약속하는 것이다.
/* @jsx createElement */
function createElement (type, attributes, ...children) {
return {
type,
props: {
...(attributes ?? {}),
children: children.length <= 1 ? children[0] : children,
},
key: null,
};
}
function renderAsync(element): Promise<string> {
if (element === null || element === undefined || element === false) {
return Promise.resolv("");
}
if (typeof element === "string") {
return Promise.resolv(element);
}
if (typeof element === "number") {
return Promise.resolv(element.toString());
}
if (Array.isArray(element)) {
return Promise.resolv(element.map((el) => renderNode(el)).join(""));
}
if (typeof element.type === "function") {
return render(element.type(element.props));
}
if (element.type === 'mdAwait') {
return element.props.children;
}
throw new Error("Invalid element");
}
function Heading ({ children, level }: Props) {
return <md-text>{'#'.repeat(level)} {children}</md-text>
}
renderAsync(<Heading level={1}>Test</Heading>).then((result) =>
assert.strictEqual(result, '# Test')
);
이제 어떡하지?
우선, 이 글이 재미있고 과학 기술, 창업, 그리고 이를 어떻게 결합시키는지에 대한 정보를 더 알고 싶다면 마음대로 읽으세요.
jsx-md와jsx-readme는 모두 기원된 것이기 때문에 코드가 이해하기 쉬우므로 마음대로 돌아다닐 수 있습니다.
만약 당신이 흥미가 있다면, 아마도 이 저장소들을 위해 더 많은 가격 인하의 총잡이를 확보하고, 도중에 React의 핵심을 이해하고 싶을 것입니다.
Reference
이 문제에 관하여(제 JSX 렌더기가 뭘 가르쳐줬는지 적어주세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/the_startup_cto/what-writing-my-own-jsx-renderer-taught-me-about-react-2gah텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)