React學習之擴展LinkedStateMixin雙向綁定(三十五)

緊急事件提示

這玩意已經被React v15給拋棄了,請直接用數據設置和函數處理。

引用

import LinkedStateMixin from 'react-addons-linked-state-mixin' // ES6
var LinkedStateMixin = require('react-addons-linked-state-mixin') // ES5 with npm
var LinkedStateMixin = React.addons.LinkedStateMixin; // ES5 with react-with-addons.js

1.概要

LinkedStateMixin是一種簡單表達React雙向綁定的方式(angularjs的趕腳)

React裏面,數據流是一個方向的:從擁有者到子節點。這是因爲馮·諾依曼模型便是如此,數據僅向一個方向傳遞。你可以認爲它是單向數據綁定。

然而,有很多應用需要你讀取一些數據,然後傳回給你的程序。例如,在開發表單的時候,當你接收到用戶輸入時,你將會頻繁地想更新某些React state。或者你想在JavaScript中處理佈局,然後反應到某些DOM元素的尺寸上。

React中,你可以通過監聽一個change事件來實現這個功能,從你的數據源(通常是DOM)讀取,然後在你某個組件上調用setState()[ 關閉數據流循環保持數據的單向性] 明顯會引導寫出更加容易理解的和維護的程序。

雙向綁定 – 隱式地強制使DOM裏面的數據總是和某些React state數據的值保持一致 – 這樣就可以更容易的支持其他應用。我們已經提供了LinkedStateMixin:如上所述,是一種設置通用數據流循環模型的語法糖,或者說“關聯”某些數據到React state,又或者說實現雙方數據的一致性。

注意

LinkedStateMixin僅僅是一個onChange/setState()模式的簡單包裝和約定。它不會從根本上改變數據在你的React應用中如何流動,也就是說其實LinkedStateMixin本質還是單向流,只是通過onChange將數據更改傳遞給React,然後內部數據改變就自動調用setState來進行更新。

2.LinkedStateMixin:前後對比

這是一個簡單的表單示例,沒有使用LinkedStateMixin

var NoLink = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({message: event.target.value});
  },
  render: function() {
    var message = this.state.message;
    return <input type="text" value={message} onChange={this.handleChange} />;
  }
});

這段代碼運行地很好,數據如何流動是非常清晰的,但是,如果表單有大量的字段,代碼就會很冗長了。讓我們使用LinkedStateMixin來減少代碼量(如今React v15並不希望你使用這個玩意)。

var WithLink = React.createClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

LinkedStateMixin給你的React組件添加一個叫做linkState()的方法。linkState()返回一個包含React state當前的值和用來改變它的回調函數的valueLink對象。

valueLink 對象可以在樹中作爲props被向上傳遞或者向下傳遞,所以它在組件層和狀態層建立起雙向綁定是非常簡單的。

注意

對於checkboxvalue屬性,有一個特殊的行爲,如果checkbox被選中(默認是on),value屬性值將會在表單提交的時候發送出去。當checkbox被選中或者取消選中的時候,value屬性是不會更新的。對於checkbox,你應該使用checkLink而不是valueLink

<input type="checkbox" checkedLink={this.linkState('booleanValue')} />

3.底層原理

對於LinkedStateMixin,有兩點:你創建valueLink實例的地方和你使用它的地方。
爲了證明LinkedStateMixin 是多麼的簡單,讓我們單獨地重寫每一塊兒,以便顯得更加明瞭。

valueLink不帶LinkedStateMixin

var WithoutMixin = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  handleChange: function(newValue) {
    this.setState({message: newValue});
  },
  render: function() {
    var valueLink = {
      value: this.state.message,
      requestChange: this.handleChange
    };
    return <input type="text" valueLink={valueLink} />;
  }
});`

如你所見,valueLink 對象是非常簡單的,僅僅有一個valuerequestChange屬性。LinkedStateMixin也同樣簡單:它僅佔據這些字段,用來自於this.state的值和一個調用this.setState()的回調函數。

LinkedStateMixin不帶valueLink

var LinkedStateMixin = require('react-addons-linked-state-mixin');

var WithoutLink = React.createClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    var valueLink = this.linkState('message');
    var handleChange = function(e) {
      valueLink.requestChange(e.target.value);
    };
    return <input type="text" value={valueLink.value} onChange={handleChange} />;
  }
});

valueLink屬性也很簡單。它簡單地處理onChange事件,然後調用this.props.valueLink.requestChange(),同時也用this.props.valueLink.value替換this.props.value

下一篇將暫時沒有,嘿,可能是將源碼,也可能是講React的其它衍生。

發佈了447 篇原創文章 · 獲贊 471 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章