Python全棧開發學習--Reactjs--基礎語法(上)--Day12

前言

上一篇介紹了Reactjs的項目目錄結構以及他的工作模式。這篇文章將會通過閱讀官方文檔,學習Reactjs的語法,邏輯,思想等內容。

文章目錄

1、JSX
2、元素
3、組件

一、JSX

1、JSX

前面我們瞭解到React是通過js來構造html,實際上React就是通過JSX來渲染元素,那麼什麼是JSX,它跟JS和HTML有什麼關聯呢?

2、JSX簡介

JSX(JavaScript XML)是 js 內定義的一套類 XML 語法,可以解析出目標 js 代碼,顛覆傳統 js 寫法。初接觸JSX的語法,可能會讓人聯想到html模板語言,其實JSX做的工作與HTML所做的工作有一定的相似之處,不用的地方在於,HTML 由瀏覽器解析,而 JSX 是由 js 解析。

使用JSX可以生成React元素。JSX在被編譯後也會轉化成js代碼執行。React中用不用JSX不是一個硬性條件,只是說使用JSX會有更多的好處。

總而言之,能有JSX做的事,用javascript都能做到。

3、舉個栗子(在html文檔中創造一個列表)

3.1 JS
var child1 = React.createElement('li', null, '這是列表下的第一條元素');
var child2 = React.createElement('li', null, '這是列表下的第二條元素');
var new_list = React.createElement('ul', { className: 'my-list' }, child1, child2);
3.2 JSX
const new_list = (
  <ul className="my-list">
    <li>這是列表下第一條元素</li>
    <li>這是列表下第一條元素</li>
  </ul>
)

Babel 會把 JSX 轉譯成一個名爲 React.createElement() 函數調用。上述兩種方法實現的效果是一樣的。

4、JSX語法

4.1 JSX 的基本語法規則:

1)遇到 HTML 標籤(以 < 開頭),就用 HTML 規則解析
2)遇到代碼塊(以 { 開頭),就用 JavaScript 規則解析

4.2 JSX 語法示例:
const element = <h1>Hello, world!</h1>;

/* 若一個標籤裏面沒有內容,可以使用 /> 來閉合標籤 */
const element = <img src={user.avatarUrl} />;
4.3 表達式嵌套

1、在JSX中,我們還可以使用表達式

/* 通過 { } 接收參數 name  */
const name = 'Reactjs';
const element = <h1>Hello, {name}</h1>;

2、在JSX中,我們可以在大括號內放置任何有效的 JavaScript 表達式。這些表達式可以爲:

(1)變量名
(2)函數定義表達式
(3)屬性訪問表達式
(4)函數調用表達式
(5)算數表達式
(6)關係表達式
(7)邏輯表達式

1、放置算數表達式:
const element = <h1>計算10+5的結果:{10+5}</h1>;

2、放置調用函數:

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = <h1>Hello, {formatName(user)}</h1>;

3、JSX作爲表達式返回

/* 可以在其他 javascript 中返回 JSX 生成的 DOM 對象 */
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}
4.4 命名規則

因爲 JSX 語法上更接近 JavaScript 而不是 HTML,所以 React DOM 節點使用 camelCase(小駝峯命名)來定義屬性的名稱,而不使用 HTML 屬性名稱的命名約定。

例如,JSX 裏的 class 變成了 className,而 tabindex 則變爲 tabIndex

4.5 JSX 對象
const element = <h1 className="greeting">Hello, world!</h1>;

上述JSX語法生成的對象結構:

const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

這些對象被稱爲 “React 元素”。它們描述了你希望在屏幕上看到的內容。React 通過讀取這些對象,然後使用它們來構建 DOM 以及保持隨時更新

二、元素

元素是構成 React 應用的最小磚塊。它描述了你在屏幕上想看到的內容。也就是我們日常瀏覽網頁時看到的網頁上的圖片,文字,表格,列表等等,這些都是由一個或者多個元素組成。

例如:<a><h1><div><span><img>

渲染元素也就是畫畫,將定義的元素在網頁中繪製出來,將react渲染成爲一個html DOM

1、ReactDOM

我們在使用react開發網頁時,會下載兩個包,一個是react,一個是react-dom,其中react包是react的核心代碼,react-dom則是React剝離出的涉及DOM操作的部分。

react的核心思想是虛擬DOM,react包含了生成虛擬DOM的函數react.createElement,及Component類。當我們自己封裝組件時,就需要繼承Component類,才能使用生命週期函數等。

react-dom包的核心功能就是把這些虛擬DOM渲染到文檔中變成實際DOM。下面學習 ReactDOM 的 API 函數

1.1 render()

render用於將React渲染的虛擬DOM渲染到瀏覽器DOM,一般在頂層組件使用

(1)語法

render(ReactElement element,DOMElement container,[function callback])
@param:
ReactElement element:待渲染的元素或者組件
DOMElement container:容器節點(已經存在的DOM節點)
[function callback]:回調函數

(2)例子


import ReactDOM from 'react-dom';

/* 渲染組件*/
/* <Example /> 爲自定義組件 */
ReactDOM.render(<Example />, document.getElementById('root'));

/* 渲染元素 */
const element = <h1>Hello, world!</h1>;
ReactDOM.render(element, document.getElementById('root'));

(3)一些注意事項

1)ReactDOM.render()會控制傳入容器節點裏的內容。當首次調用時,容器節點裏的所有 DOM 元素都會被替換,後續的調用則會使用 React 的 DOM 差分算法(DOM diffing algorithm)進行高效的更新。

2)ReactDOM.render() 不會修改容器節點(只會修改容器的子節點)。可以在不覆蓋現有子節點的情況下,將組件插入已有的 DOM 節點中。

1.2 findDOMNode()

當我們通過render()方法將組件渲染成DOM以後,避免不了獲取該組件的操作,通過findDOMNode()方法可以返回已經完成渲染的組件對應的DOM節點。

(1)語法

ReactDOM.findDOMNode(component)

(2)注意事項

1)findDOMNode 是一個訪問底層 DOM 節點的應急方案。在大多數情況下,不推薦使用該方法,因爲它會破壞組件的抽象結構

2)大多數情況下,你可以綁定一個 ref 到 DOM 節點上,可以完全避免使用 findDOMNode。

3)findDOMNode 只在已掛載的組件上可用(即,已經放置在 DOM 中的組件)。如果你嘗試調用未掛載的組件(例如在一個還未創建的組件上調用 render() 中的 findDOMNode())將會引發異常。

4)findDOMNode 不能用於函數組件。

1.3 unmountComponentAtNode()

從 DOM 中卸載組件,會將其事件處理器(event handlers)和 state 一併清除。如果指定容器上沒有對應已掛載的組件,這個函數什麼也不會做。如果組件被移除將會返回 true,如果沒有組件可被移除將會返回 false。

(1)語法

ReactDOM.unmountComponentAtNode(container)

2、更新元素

React DOM 會將元素和它的子元素與它們之前的狀態進行比較,並只會進行必要的更新來使 DOM 達到預期的狀態。

計時器例子:

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

對於上述例子,render每次渲染的時候,都只對h2進行更新,對於沒有改變的元素,render不會對其進行重新渲染。這裏面涉及到一個react的差分算法

三、組件

首先需要區分組件跟元素的概念,組件是由元素構成的。元素數據結構是普通對象,而組件數據結構是類或純函數。

就拿建造一座大樓來說,
如果說我們最後使用React構建的網頁一座輝煌的高樓。
那麼,元素就是磚塊,組件就是每一間房間,例如廁所組件、臥室組件、廚房組件,這些組件都是一塊一塊磚構成,這一座樓房又是有這些房間組件構成。
在這裏插入圖片描述

1、函數組件

定義組件最簡單的方式就是編寫 JavaScript 函數:

function Hello(props) {
  return <h1>Hello, {props.name}</h1>;
}

2、class組件

定義 class 組件,需要繼承 React.Component:

class Hello extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

3、渲染組件

回顧之前的元素,發現到目前爲止,遇到到React元素都是html DOM 標籤,例如

const element = <div />;
const element = <a />;
const element = <img />;

React 元素也可以是用戶自定義的組件:

const element = <Hello name="Lisa" />;

上面定義了一個名叫Hello的組件

function Hello(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Hello name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

1、調用 ReactDOM.render() 函數,並傳入 <Hello name="Sara" /> 作爲參數。
2、React 調用 Hello 組件,並將 {name: 'Lisa'} 作爲 props 傳入。
3、Hello 組件將 <h1>Hello, Lisa</h1> 元素作爲返回值。
4、React DOMDOM 高效地更新爲 <h1>Hello, Lisa</h1>

4、自定義組件規則

組件名稱必須以大寫字母開頭

以小寫字母開頭的元素代表一個 HTML 內置組件,比如 <div> 或者 <span> 會生成相應的字符串 ‘div’ 或者 ‘span’ 傳遞給React.createElement(作爲參數)。大寫字母開頭的元素則對應着在 JavaScript 引入或自定義的組件,如 <Foo /> 會編譯爲 React.createElement(Foo)。

import React from 'react';

// 錯誤!組件應該以大寫字母開頭:
function hello(props) {
  // 正確!這種 <div> 的使用是合法的,因爲 div 是一個有效的 HTML 標籤
  return <div>Hello {props.toWhat}</div>;
}

// 正確!組件以大寫字母開頭了:
function HelloWorld() {
  // 錯誤!React 會認爲 <hello /> 是一個 HTML 標籤,因爲它沒有以大寫字母開頭:
  return <hello toWhat="World" />;
}

5、混合組件

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      /* 調用自定義的 Welcome 組件*/
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章