国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

React數據傳遞之組件內部通信的方法

2019-11-19 14:37:19
字體:
來源:轉載
供稿:網友

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 (  <div className="App">  <p>{this.state.inputValue}</p>  </div> ); }}

在通過 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 中'{}'里面代表函數表達式,// 所以傳遞給 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 (  <div className="App">  <button onClick={this.handleClick}>   {this.state.isToggleOn ? "on" : "off"}  </button>  </div> ); }}

2.2.3 為什么會有坑

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

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

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

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

var fn = function () { console.log(this);};var a = fn;fn(); // windowa(); // windowthis 指向發生改變的例子:var fn = function () { console.log(this);};// 將函數體賦值給一個對象的屬性,函數執行時 this 和定義時指向不同var o = { a: fn,};fn(); // windowo.a(); // o,即{a:f}

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

var fn = function () { console.log(this);};// fn 在賦值的同時將內部的 this 打包一塊賦值給了 avar o = { a: fn.bind(this),};fn(); // windowo.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: 'button', props: { onClick: this.handleClick, children: 'click me', },};


這實際就是 將函數體賦值給一個對象的屬性,函數執行時 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 (   <div className="App">    <input value={this.state.inputValue} onChange={this.changeInput} />    <p>{this.state.inputValue}</p>   </div>  ); }}

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳朔县| 济源市| 五常市| 宝清县| 通海县| 平顺县| 石城县| 仙游县| 隆昌县| 邹城市| 普宁市| 宁武县| 北宁市| 隆安县| 甘泉县| 大埔区| 黄陵县| 肥乡县| 西吉县| 工布江达县| 亚东县| 聂拉木县| 静安区| 龙陵县| 公安县| 阿拉善右旗| 吉林省| 广河县| 固始县| 喀喇沁旗| 济南市| 涿鹿县| 贵溪市| 五指山市| 东源县| 安泽县| 确山县| 杭锦旗| 新疆| 彭泽县| 玉林市|