Einer der Schwachpunkte beim Lesen des Quellcodes besteht darin, dass Sie in das Dilemma geraten, das Rückgrat nicht zu begradigen. Diese Artikelserie implementiert ein (x)react und begradigt gleichzeitig den Grundgerüstinhalt des React-Frameworks (JSX). /virtual DOM/components/... )
Im vorherigen Artikel JSX und Virtual DOM wurde der Prozess des Renderns von JSX an die Schnittstelle erläutert und der entsprechende Code implementiert . Der Codeaufruf lautet wie folgt:
import React from 'react' import ReactDOM from 'react-dom' const element = ( <p> hello<span>world!</span> </p> ) ReactDOM.render( element, document.getElementById('root') )
In diesem Abschnitt werden wir den Prozess des Komponenten-Renderings an die Schnittstelle weiter untersuchen. Hier stellen wir das Konzept der Komponenten vor, 组件本质上就是一个函数
, das Folgende ist ein Standardkomponentencode:
import React from 'react' // 写法 1: class A { render() { return <p>I'm componentA</p> } } // 写法 2:无状态组件 const A = () => <p>I'm componentA</p> ReactDOM.render(<a></a>, document.body)
<a name="componentA"></a>
ist die Art und Weise, JSX zu schreiben, genau wie im vorherigen Artikel, Babel konvertiert ihn in React. createElement( ) in der Form Wie folgt:
React.createElement(A, null)
Beachten Sie, dass der Knotenname im zurückgegebenen virtuellen DOM ebenfalls zu einer Funktion geworden ist. Basierend auf diesen Hinweisen transformieren wir die vorherige <a name="componentA"></a>
-Funktion.
{ attributes: undefined, children: [], key: undefined, nodeName: ƒ A() }
An diesem Punkt haben wir die Verarbeitungslogik der Komponente abgeschlossen. render
function render(vdom, container) { if (_.isFunction(vdom.nodeName)) { // 如果 JSX 中是自定义组件 let component, returnVdom if (vdom.nodeName.prototype.render) { component = new vdom.nodeName() returnVdom = component.render() } else { returnVdom = vdom.nodeName() // 针对无状态组件:const A = () => <p>I'm componentsA</p> } render(returnVdom, container) return } }
import React, { Component } from 'react' class A extends Component { render() { return <p>I'm {this.props.name}</p> } } ReactDOM.render(<a></a>, document.body)
function Component(props) { this.props = props this.state = this.state || {} }
function render(vdom, container) { if (_.isFunction(vdom.nodeName)) { let component, returnVdom if (vdom.nodeName.prototype.render) { component = new vdom.nodeName(vdom.attributes) // 将组件外的 props 传进组件内 returnVdom = component.render() } else { returnVdom = vdom.nodeName(vdom.attributes) // 处理无状态组件:const A = (props) => <p>I'm {props.name}</p> } ... } ... }
Es ist offensichtlich nicht das, was wir in setState schreiben möchten. Wir übertragen den Dom-Knoten, der sich auf die _render-Funktion bezieht:
function Component(props) { this.props = props this.state = this.state || {} } Component.prototype.setState = function() { this.state = Object.assign({}, this.state, updateObj) // 这里简单实现,后续篇章会深入探究 const returnVdom = this.render() // 重新渲染 document.getElementById('root').innerHTML = null render(returnVdom, document.getElementById('root')) }
Rekonstruieren Sie natürlich die damit verbundene Render-Funktion : document.getElementById('root')
Component.prototype.setState = function(updateObj) { this.state = Object.assign({}, this.state, updateObj) _render(this) // 重新渲染 }
function render(vdom, container) { let component if (_.isFunction(vdom.nodeName)) { if (vdom.nodeName.prototype.render) { component = new vdom.nodeName(vdom.attributes) } else { component = vdom.nodeName(vdom.attributes) // 处理无状态组件:const A = (props) => <p>I'm {props.name}</p> } } component ? _render(component, container) : _render(vdom, container) }
function _render(component, container) { const vdom = component.render ? component.render() : component if (_.isString(vdom) || _.isNumber(vdom)) { container.innerText = container.innerText + vdom return } const dom = document.createElement(vdom.nodeName) for (let attr in vdom.attributes) { setAttribute(dom, attr, vdom.attributes[attr]) } vdom.children.forEach(vdomChild => render(vdomChild, dom)) if (component.container) { // 注意:调用 setState 方法时是进入这段逻辑,从而实现我们将 dom 的逻辑与 setState 函数分离的目标;知识点: new 出来的同一个实例 component.container.innerHTML = null component.container.appendChild(dom) return } component.container = container container.appendChild(dom) }
An diesem Punkt haben wir die Logik der Requisiten und Zustandsteile implementiert.
ZusammenfassungKomponenten sind Funktionen; wenn JSX eine benutzerdefinierte Komponente ist, wird der erste Parameter in React.createElement(fn, ..) nach der Babel-Konvertierung zu einer Funktion, mit der Ausnahme, dass die andere Logik die ist Das Gleiche gilt, wenn es sich um ein HTML-Element in JSX handelt. Darüber hinaus kapseln wir APIs wie state/props/setState in die übergeordnete Klasse React.Component, damit diese Eigenschaften und Methoden in Unterklassen aufgerufen werden können . Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website. Verwandte Empfehlungen:Detaillierte Erklärung von config/index.js in vue: Konfiguration
Erklärung der Angular-Vorlagensyntax
Das obige ist der detaillierte Inhalt vonParsen von React-Komponenten und State|Props. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!