首頁 web前端 js教程 在React中如何實現組件內部通信

在React中如何實現組件內部通信

Jun 14, 2018 pm 03:24 PM

這篇文章主要介紹了React資料傳遞之組件內部通訊的方法,現在分享給大家,也給大家做個參考。

1. 概述

脫離初級前端一段時間後會發現,寫樣式的時間越來越少,處理資料的時間越來越多。處理資料的過程也就是實現業務邏輯的過程,這在專案中無疑是最重要的。

所以學習前端框架,了解完基本文法後,接下來就要學習如何進行資料傳遞。

Angular 設計之初的一大亮點就是實現了資料的雙向綁定,使用Vue 一段時間後發現,所謂資料的雙向綁定,元件內部唯一的應用場景就是form 表單(input,textarea ,select, radio),而這種場景下的資料雙向綁定,即便框架內部沒有實現,自己實現起來也非常簡單。明白這一點後感覺之前認為 React 沒有實現資料雙向綁定很 low 的想法很幼稚。

對於React 的資料傳遞,涉及兩方面的內容:

  1. #元件內部的資料傳遞,典型的應用場景包括如何實作form 表單雙向資料綁定、如何綁定事件;

  2. 元件間的資料傳遞。包含父元件往子元件傳遞資料、子元件往父元件傳遞資料、兄弟元件之間傳遞資料。

本文先討論元件內部的資料傳遞。

2. 元件內部資料傳遞

React 元件內部通訊主要分為兩部分:資料展示與事件處理。

2.1 資料顯示

元件內部資料的展示和更新都是透過 state 來實現的,如果要使用 state 必須使用 ES6 的 class 定義元件。資料更新在雙向資料綁定部分探討,這部分僅討論展示初始化資料。

如果你熟悉Vue,React 的state 物件相當於Vue 的data 物件

下面是一個純粹展示資料的範例:

class App extends Component {
 constructor(props) {
 super(props);

 // 初始化 state
 this.state = {
  inputValue: "test",
 };
 }

 render() {
 // 注意,在 react 中,DOM 元素是对象,所以使用‘()'包住 
 return (
  <p className="App">
  <p>{this.state.inputValue}</p>
  </p>
 );
 }
}
登入後複製

在透過class 定義的React 元件中,除了生命週期鉤子函數, constructor() 和render() 著兩個方法也是自動執行的,先執行constructor() ,執行constructor() 的同時也是再為render() 渲染DOM 做資料準備。

實際上 constructor() 函數是元件生命週期中呼叫的第一個函數。

2.2 事件

2.2.1 與DOM 中事件的異同

在React 中處理事件和在DOM 中處理事件類似,有兩點不同:

  1. React 中透過駝峰命名法命名事件,而不是全是小寫字母;

  2. 在JSX 中直接傳遞函數作為事件處理程序,而不是字串。

第2 點不同有坑,後面細說

舉個例子,HTML中的事件:

<button onclick="activateLasers()">
 Activate Lasers
</button>
登入後複製

React 中的事件:

// 因为 jsx 中&#39;{}&#39;里面代表函数表达式,
// 所以传递给 onClick 的实际是函数 activateLasers 的函数体部分,
// 因此需要指定 this 指向,不然会报错
<button onClick={activateLasers}>
 Activate Lasers
</button>
登入後複製

2.2.2 存在的坑

直接傳遞function 作為event handler 需要指定函數的執行環境,即需要手動綁定this ,否則會報this 為undefined的錯。請看下面的例子:

class App extends Component {
 constructor(props) {
 super(props);
 this.state = {
  isToggleOn: true,
 };

 // 手动绑定 this
 this.handleClick = this.handleClick.bind(this);
 }

 handleClick() {
 // 如果不在 constructor() 方法中手动绑定 this,直接将其作为事件处理程序 this 为 undefined
 console.log(this);

 this.setState(prevState => ({
  isToggleOn: !prevState.isToggleOn
 }));
 }

 render() {
 return (
  <p className="App">
  <button onClick={this.handleClick}>
   {this.state.isToggleOn ? "on" : "off"}
  </button>
  </p>
 );
 }
}
登入後複製

2.2.3 為什麼會有坑

React 官網說這個鍋要JS 原生語法來背,其實不盡然,React 實在JS 語法早已確定的情況下設計了這樣的事件系統,如果一定要有人站出來背鍋,他們五五分吧。

1, JS原生語法存在的問題

JS語法中有這樣的規則:如果將一個函數的函數體(沒有() )賦值給另一個變量,函數體內部的this 指向可能會改變。會不會變化取決於函數和被賦值的變數是否處於同一個作用域(相同的執行環境)中,但實際使用中,將一個函數賦值給相同作用域的變數沒有意義,那樣的話直接使用那個函數就好,沒必要在賦值給另一個變數。

this 指向不發生改變的沒有意義的例子(為了方便說明,直接使用var 運算子):

var fn = function () {
 console.log(this);
};

var a = fn;

fn(); // window
a(); // window
this 指向发生改变的例子:

var fn = function () {
 console.log(this);
};

// 将函数体赋值给一个对象的属性,函数执行时 this 和定义时指向不同
var o = {
 a: fn,
};

fn(); // window
o.a(); // o,即{a:f}
登入後複製

如果想要在將函數體賦值另一個變數的同時把原函數的this 指向也一塊賦值過去,就需要在賦值的過程中進行綁定this 的操作,如下:

var fn = function () {
 console.log(this);
};

// fn 在赋值的同时将内部的 this 打包一块赋值给了 a
var o = {
 a: fn.bind(this),
};

fn(); // window
o.a(); // window
登入後複製

通常在將函數體賦值給變數的時候為了避免this 出錯,都會進行綁定定執行環境的操作,典型的例子是var bindId = document.getElementById.bind(document)

2, JSX 存在的問題

#因為JSX 中DOM 元素也是對象,給元素的屬性賦值實際上是給DOM 元素對象的屬性賦值,見下:

const element = (
 <button onClick={this.handleClick}>click me</button>
);
登入後複製

等同於

const element = {
 type: &#39;button&#39;,
 props: {
 onClick: this.handleClick,
 children: &#39;click me&#39;,
 },
};
登入後複製


這實際上就是將函數體賦值給一個對象的屬性,函數執行時this 和定義時指向不同的場景,和原生語法相同的是this 指向發生了改變,不同的是原生JS 中不管怎樣, this 總歸是有個指向的,而JSX 直接undefined 。

所以說不綁定 this 報 undefined 的錯不能全怪 JS 原生語法。

3. 双向数据绑定

通过 state 传递数据加上事件处理程序便能实现数据的双向绑定,其背后的思想是(以 input 为例):初始化时将 state 中预定义的 state a 赋值给 input,当 input 的 value 发生改变时,触发事件处理程序,将改变后的 value 赋值给状态 a ,React 监测到 state 改变时重新调用 render() 方法,即重新渲染组件,达到双向绑定的目的。

class App extends Component {
 constructor(props) {
  super(props);
  this.state = {
   inputValue: "test",
  };
  this.changeInput = this.changeInput.bind(this);
 }

 changeInput(e) {
  // 将改变后的 input 值赋值给 inputValue,通过事件对象 $event.target.value 实现
  this.setState({
   inputValue: e.target.value
  });
 }

 render() {
  // input 改变时触发 changeInput
  return (
   <p className="App">
    <input value={this.state.inputValue} onChange={this.changeInput} />
    <p>{this.state.inputValue}</p>
   </p>
  );
 }
}
登入後複製

这里用到了事件对象,React 的事件对象和 JS 原生事件对象保持一致。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用Node.js爬虫如何实现网页请求

使用VueAwesomeSwiper容易出现的问题?

在angular2中有关Http请求原理(详细教程)

在node中如何实现http小爬虫

以上是在React中如何實現組件內部通信的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

前端熱敏紙小票打印遇到亂碼問題怎麼辦? 前端熱敏紙小票打印遇到亂碼問題怎麼辦? Apr 04, 2025 pm 02:42 PM

前端熱敏紙小票打印的常見問題與解決方案在前端開發中,小票打印是一個常見的需求。然而,很多開發者在實...

神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

誰得到更多的Python或JavaScript? 誰得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

如何使用JavaScript將具有相同ID的數組元素合併到一個對像中? 如何使用JavaScript將具有相同ID的數組元素合併到一個對像中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中將具有相同ID的數組元素合併到一個對像中?在處理數據時,我們常常會遇到需要將具有相同ID�...

JavaScript難以學習嗎? JavaScript難以學習嗎? Apr 03, 2025 am 12:20 AM

學習JavaScript不難,但有挑戰。 1)理解基礎概念如變量、數據類型、函數等。 2)掌握異步編程,通過事件循環實現。 3)使用DOM操作和Promise處理異步請求。 4)避免常見錯誤,使用調試技巧。 5)優化性能,遵循最佳實踐。

如何實現視差滾動和元素動畫效果,像資生堂官網那樣?
或者:
怎樣才能像資生堂官網一樣,實現頁面滾動伴隨的動畫效果? 如何實現視差滾動和元素動畫效果,像資生堂官網那樣? 或者: 怎樣才能像資生堂官網一樣,實現頁面滾動伴隨的動畫效果? Apr 04, 2025 pm 05:36 PM

實現視差滾動和元素動畫效果的探討本文將探討如何實現類似資生堂官網(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

console.log輸出結果差異:兩次調用為何不同? console.log輸出結果差異:兩次調用為何不同? Apr 04, 2025 pm 05:12 PM

深入探討console.log輸出差異的根源本文將分析一段代碼中console.log函數輸出結果的差異,並解釋其背後的原因。 �...

See all articles