Heim > Web-Frontend > js-Tutorial > Hauptteil

Parsen von React-Komponenten und State|Props

不言
Freigeben: 2018-07-13 15:10:24
Original
1448 Leute haben es durchsucht

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/... )

Komponenten sind Funktionen

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')
)
Nach dem Login kopieren

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)
Nach dem Login kopieren

<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)
Nach dem Login kopieren

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()
}
Nach dem Login kopieren

An diesem Punkt haben wir die Verarbeitungslogik der Komponente abgeschlossen. render

Implementierung von Requisiten und Zuständen

In der Komponente A im vorherigen Abschnitt wurden keine Eigenschaften und Zustände eingeführt. Wir hoffen, dass Eigenschaften (Requisiten) zwischen Komponenten und den internen Funktionen von übertragen werden können Die Komponenten können den Zustand (State) aufzeichnen.

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
  }
}
Nach dem Login kopieren

Im obigen Code sehen Sie, dass die A-Funktion von Component erbt. Lassen Sie uns diese Komponente der übergeordneten Klasse erstellen und ihr Status, Requisiten, SetState und andere Attributmethoden hinzufügen, damit Unterklassen sie erben können.

import React, { Component } from 'react'

class A extends Component {
  render() {
    return <p>I'm {this.props.name}</p>
  }
}

ReactDOM.render(<a></a>, document.body)
Nach dem Login kopieren
Zuerst übergeben wir die Requisiten von außerhalb der Komponente in die Komponente und ändern den folgenden Code in der Renderfunktion:

function Component(props) {
  this.props = props
  this.state = this.state || {}
}
Nach dem Login kopieren
Nachdem die Übertragung der Requisiten zwischen den Komponenten abgeschlossen ist, sprechen wir über den Status . Im obigen Beispiel wird setState verwendet, um die Änderung des Komponentenstatus abzuschließen (asynchron). Die einfache Implementierung hier ist wie folgt:

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>
    }
    ...
  }
  ...
}
Nach dem Login kopieren
Obwohl die setState-Funktion vorhanden ist wurde zu diesem Zeitpunkt implementiert.

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'))
}
Nach dem Login kopieren

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) // 重新渲染
}
Nach dem Login kopieren
Der Zweck der Trennung der _render-Funktion von der Render-Funktion besteht darin, den Aufruf der _render-Logik in der setState-Funktion zu ermöglichen. Die vollständige _render-Funktion lautet wie folgt:

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)
}
Nach dem Login kopieren
Lassen Sie uns den folgenden Anwendungsfall verwenden, um die geschriebene Reaktion auszuführen!

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)
}
Nach dem Login kopieren
Das Rendering ist wie folgt:

An diesem Punkt haben wir die Logik der Requisiten und Zustandsteile implementiert. Parsen von React-Komponenten und State|Props

Zusammenfassung

Komponenten 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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!