国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MobX

Alliot / 588人閱讀

摘要:建議將它們用于修改可觀察量或具有副作用的任何函數(shù)中。這意味著在一些定時器或者網(wǎng)絡(luò)請求,異步處理的情況下,它們的回調(diào)函數(shù)無法對狀態(tài)做成改變。這些回調(diào)函數(shù)都應(yīng)該有包裹,如果例子里面的一樣。

1. 介紹 1.1. 原理

React的render是 狀態(tài) 轉(zhuǎn)化為樹狀結(jié)構(gòu)的渲染組件的方法
而MobX提供了一種存儲,更新 狀態(tài) 的方法
React 和 MobX都在優(yōu)化著軟件開發(fā)中相同的問題。
React 使用的方法是讓虛擬DOM來減少繁瑣而沉重的DOM變化。
而MobX則通過一個虛擬的狀態(tài)依賴圖表來讓react組件和應(yīng)用狀態(tài)同步化來減少不必要的狀態(tài)導(dǎo)致組件更新

1.2. 安裝

MobX:

npm install mobx --save

React bindings:

npm install mobx-react --save
1.3. 要點

MobX看起來很復(fù)雜的樣子,其實是用它只需要三步

定義你的狀態(tài),讓它們成為觀察者(observable)
存儲狀態(tài)(Store state)可以是任何的數(shù)據(jù)結(jié)構(gòu),隨你定義為:對象,數(shù)組,類,循環(huán)結(jié)構(gòu),引用都沒所謂。但需要記住一點,就是:隨著時間的變化,用MobX 去把它們定義成觀察者(observable)

import {observable} from "mobx"
let appState = observable({
    timer: 0
})

我們不需要讓appState去觀察什么。你現(xiàn)在就能創(chuàng)建視圖(view),每當(dāng)appState的相關(guān)數(shù)據(jù)發(fā)生變化的時候,就會自動更新。MobX會采用最優(yōu)的方式去更新你的視圖。以下有一個例子來說明如何使用,其中使用了ES6/ES7的語法(當(dāng)然MobX也是支持ES5),代碼中@的意義

import {observer} from "mobx-react";
@observer
class TimerView extends React.Component {
    render() {
        return ();
    }
    onReset () {
        //appState.resetTimer會在下一節(jié)完成
        this.props.appState.resetTimer();
    }
};
React.render(, document.body);

修改狀態(tài)
第三節(jié)要說的是修改狀態(tài)。MobX和其他框架不同,它不會要求你去做什么事情,它只是幫助你去做簡單的事情

appState.resetTimer = action(function reset() {
    appState.timer = 0;
});
setInterval(action(function tick() {
    appState.timer += 1;
}), 1000);

其中action包裝用法只能在strict模式下使用,請記得在你的javascript文件頭寫上:"use strict"。

2. API

從上面的例子可以看到,MobX的API其實不多:observable, computed, reactions, actions

2.1. observable(value)

其中的value可以是JS原定的數(shù)據(jù)結(jié)構(gòu),引用,對象,數(shù)組,ES6的map

如果value是一個map的話,則需要使用一個調(diào)節(jié)器(modifier)asMap來使用。這時候會返回一個Observable Map

如果是一個數(shù)組,返回Observable Array

如果是一個沒有屬性的對象,則返回一個Observable Object

如果是一個有屬性的對象,JS原有的數(shù)據(jù)結(jié)構(gòu),函數(shù)等,返回一個 Boxed Observable。MobX不會自動讓一個有屬性的對象成為觀察者。這是這個有屬性的對象的構(gòu)造函數(shù)應(yīng)該做的事情,你可以使用extendObservable在它的構(gòu)造函數(shù)里面,或者在它的類使用@observable去定義。

以下是一些例子:

const map = observable(asMap({ key: "value"}));
map.set("key", "new value");

const list = observable([1, 2, 4]);
list[2] = 3;

const person = observable({
    firstName: "Clive Staples",
    lastName: "Lewis"
});
person.firstName = "C.S.";

const temperature = observable(20);
temperature.set(25);
2.2. @observable
import {observable} from "mobx";
class OrderLine {
    @observable price:number = 0;
    @observable amount:number = 1;
    constructor(price) {
        this.price = price;
    }
    //這里在下一節(jié)會說到
    @computed get total() {
        return this.price * this.amount;
    }
}
const line = new OrderLine();
console.log("price" in line); // true
//hasOwnProperty:判斷一個對象是否有你給出名稱的屬性或?qū)ο蟆P枰⒁猓朔椒o法檢查該對象的原型鏈中是否具有該屬性
console.log(line.hasOwnProperty("price")); //false

如果你的環(huán)境不支持ES6/7的語法的話,其實@observable key = value; 只是extendObservable(this, { key: value })的語法糖。因此在ES5環(huán)境下你也能使用

2.3. (@)computed

Computed values 就像一個算術(shù)公式一樣去從現(xiàn)有的狀態(tài)或其他值去計算出需要的值。計算的耗費是不可低估的。Computed盡可能幫你減少其中的耗費。它們是高度優(yōu)化的,請把它用在可能用到的地方。

不要混淆下一節(jié)說到的autorun。雖然他們都是被動調(diào)用的表達(dá)式。但是……
Computed使用情況:如果你需要產(chǎn)生一個有觀察者(observers)參數(shù)計算的新的值的時候
autorun使用情況:你不想產(chǎn)生一個新的值就想達(dá)到一個新的效果/功能。就像是打log或者進(jìn)行網(wǎng)絡(luò)請求
Computed values是自動幫你從你的狀態(tài)(state)值和其他計算輔助值來計算的。MobX做了很多的優(yōu)化。當(dāng)參與計算的值沒有發(fā)生改變,Computed是不會重新運行。如果參與計算的值沒有被使用,Computed values是暫停的。

如果Computed values不再是觀察者(observed),那么在UI上也會把它除掉,MobX能自動做垃圾回收。autorun則需要你自己手動去處理。如果參與計算的值不再被使用,是不會緩存Computed的,所以重新計算是需要的。這個是最理想的默認(rèn)情況。如果你想保留,可以了解一下keepalive和observe。

例子1: 在2.2的例子。@computed get

例子2: @computed set

class Foo {
    @observable length: 2,
    @computed get squared() {
        return this.length * this.length;
    }
    set squared(value) { //this is automatically an action, no annotation necessary
        this.length = Math.sqrt(value);
    }
}

需要注意的是:setter并非用于直接改變參數(shù)計算的值,如例子中的length。而是作為一個逆推導(dǎo)。

2.4. Autorun

Autorun是用在一些你想要產(chǎn)生一個不用觀察者參與的被動調(diào)用函數(shù)里面。當(dāng)autorun被使用的時候,一旦依賴項發(fā)生變化,autorun提供的函數(shù)就會被執(zhí)行。與之相反的是,computed提供的函數(shù)只會在他有自己的觀察員(observers)的時候才會評估是否重新執(zhí)行,否則它的值被認(rèn)為是無用的。

根據(jù)這些經(jīng)驗:如果你需要一個自動運行但卻不會產(chǎn)生任何新的值的結(jié)果的函數(shù),那么請使用Autorun。其他情況請使用computed。Autorun只是作用于如果達(dá)到某個效果或者功能,而不是計算某些值。如果有一個字符串作為第一個參數(shù)存入Autorun,那么它將成為一個調(diào)試名稱。

var numbers = observable([1,2,3]);
var sum = computed(() => numbers.reduce((a, b) => a + b, 0));

var disposer = autorun(() => console.log(sum.get()));
// prints "6"
numbers.push(4);
// prints "10"
2.5. @observer

observer 函數(shù)/修飾器用于react組件。通過mobx-react依賴包來提供。它通過mobx.autorun來包裝了組件的render函數(shù),以確保組件的render函數(shù)在任何數(shù)據(jù)的更改是強(qiáng)制重新渲染

import {observer} from "mobx-react";
var timerData = observable({
    secondsPassed: 0
});
setInterval(() => {
    timerData.secondsPassed++;
}, 1000);
@observer class Timer extends React.Component {
    render() {
        return (Seconds passed: { this.props.timerData.secondsPassed }  )
    }
});
React.render(, document.body);

tips: 如果還有其他的decorators一起或者高階組件的存在,請確保observer為最內(nèi)層(優(yōu)先應(yīng)用)的修飾器。否則它可能無法工作。如果你只在ES5的環(huán)境下工作:其實observer不過是observer(class Timer ... { }) 的語法糖。

難點—組件中相關(guān)值的引用:
MobX能做的事情很多,但是它卻不能把原始的值變成觀察者(盡管可以通過包裹這個值來返回一個boxed observables的對象)。所以觀察者不是這個原始的值,而是返回后的對象的屬性值。修改一個剛才的例子:

React.render(, document.body)

這時候程序并不會工作了。傳入組件的只是timerData里面secondsPassed的當(dāng)前值。在組件里面,它是不可變的。

把你的組件內(nèi)部狀態(tài)變成可觀察的
和普通的類一樣,你可以在你的組件使用@observable修飾器。這意味著你的組件擁有了一個內(nèi)部state,而且它不需要使用react內(nèi)部提供的繁瑣的setState機(jī)制。這個內(nèi)部state能調(diào)起render函數(shù),但是卻不能準(zhǔn)確調(diào)起React的生命周期函數(shù),例如:componentShouldUpdate / componentWillUpdate。如果你想要這些,最好使用react提供的API來創(chuàng)建state。當(dāng)然也可以這樣寫

import {observer} from "mobx-react"
import {observable} from "mobx"
@observer class Timer extends React.Component {
    @observable secondsPassed = 0
    componentWillMount() {
        setInterval(() => {
            this.secondsPassed++
        }, 1000)
    }
    render() {
        return (Seconds passed: { this.secondsPassed }  )
    }
})
React.render(, document.body)

連接observer和stores
mobx-react提供了Provider組件讓你可以把傳遞下來的stores作用在react提供的上下文機(jī)制。通過連接這些stores和observer,這些observer會成為組件的屬性來使用。

const colors = observable({
   foreground: "#000",
   background: "#fff"
});
const App = () =>
  
     
  ;
const Button = observer(["colors"], ({ colors, label, onClick }) =>
  

componentWillReact
React 的組件總是從新的堆棧去渲染。因此讓它它很難判斷一個組件是否需要重新渲染。在mobx-react里面,你可以使用重新定義的生命周期componentWillReact。它只會在觀察者發(fā)生變化的時候才重新渲染。

import {observer} from "mobx-react";
@observer class TodoView extends React.Component {
    componentWillReact() {
        console.log("I will re-render, since the todo has changed!");
    }
    render() {
        return 
this.props.todo.title
; } }

componentWillReact沒有任何參數(shù),而且不會在render初始化之前執(zhí)行(componentWillMount的區(qū)別)。而當(dāng)接收新的屬性或者setState之后,它會被調(diào)用。

2.6. action

任何應(yīng)用程序都有操作(action)。action是任何改變狀態(tài)的事物。使用MobX,您可以通過標(biāo)記它們在您的代碼中顯式地顯示您的操作(action)。它會更好的幫助你組織你的代碼。建議將它們用于修改可觀察量或具有副作用的任何函數(shù)中。
需要注意的是:action是用在strict mode 中的

action(fn)
action(name, fn)
@action classMethod() {}
@action(name) classMethod () {}
@action boundClassMethod = (args) => { body }
@action(name) boundClassMethod = (args) => { body }
@action.bound classMethod() {}
@action.bound(function() {})
@action createRandomContact() {
    this.pendingRequestCount++;
    superagent
         .get("https://randomuser.me/api/")
         .set("Accept", "application/json")
         .end(action("createRandomContact-callback", (error, results) => {
                 if (error) console.error(error)
                 else {
                     const data = JSON.parse(results.text).results[0];
                     const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture)
                     contact.addTag("random-user");
                     this.contacts.push(contact);
                     this.pendingRequestCount--;
                 }
        }
))}

action 僅僅作用于當(dāng)前運行的函數(shù),而不能作用于當(dāng)前函數(shù)調(diào)用的函數(shù)。這意味著在一些定時器或者網(wǎng)絡(luò)請求,異步處理的情況下,它們的回調(diào)函數(shù)無法對狀態(tài)做成改變。這些回調(diào)函數(shù)都應(yīng)該有action包裹,如果例子里面的 createRandomContact-callback 一樣。但是,如果你使用了async / await的話,最好的方式應(yīng)該是使用 runInAction 來讓它變得更加簡單

@action /*optional*/ updateDocument = async () => {
    const data = await fetchDataFromUrl();
    /* required in strict mode to be allowed to update state: */
    runInAction("update state after fetching data", () => {
        this.data.replace(data);
        this.isSaving = true;
    })
}

Bound actions
目前看到的actions都是遵循在javascript中綁定的正常規(guī)則,但是在MobX 3引入了action.bound來自動綁定actions到目標(biāo)對象上。和action的使用不一樣,不需要一個名字參數(shù)。它的名稱始終基于綁定到屬性的操作上。需要注意的是,在箭頭函數(shù)上不要這樣使用,因為箭頭函數(shù)已經(jīng)綁定了上下文,不能在重新更改上下文

class Ticker {
    @observable this.tick = 0

    @action.bound
    increment() {
        this.tick++ // "this" will always be correct
    }
}
const ticker = new Ticker()
setInterval(ticker.increment, 1000)
后記

啟動例子項目:進(jìn)入

前端項目:npm install 或者 yarn install 打開本地的8080端口

后端部分:進(jìn)入 back文件夾,執(zhí)行npm start 打開本地的3000端口

作為對比:使用redux的例子:進(jìn)入

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81421.html

相關(guān)文章

  • mobx學(xué)習(xí)總結(jié)

    摘要:原理分析的核心就是通過觀察某一個變量,當(dāng)該變量產(chǎn)生變化時,對應(yīng)的內(nèi)的回調(diào)函數(shù)就會發(fā)生變化。回調(diào)函數(shù)若依賴外部環(huán)境,則無法進(jìn)行收集很好理解,的回調(diào)函數(shù)在預(yù)執(zhí)行的時候無法到達(dá)那一行代碼,所以收集不到。 Mobx解決的問題 傳統(tǒng)React使用的數(shù)據(jù)管理庫為Redux。Redux要解決的問題是統(tǒng)一數(shù)據(jù)流,數(shù)據(jù)流完全可控并可追蹤。要實現(xiàn)該目標(biāo),便需要進(jìn)行相關(guān)的約束。Redux由此引出了dispa...

    roundstones 評論0 收藏0
  • 【譯】Redux 還是 Mobx,讓我來解決你的困惑!

    摘要:我現(xiàn)在寫的這些是為了解決和這兩個狀態(tài)管理庫之間的困惑。這甚至是危險的,因為這部分人將無法體驗和這些庫所要解決的問題。這肯定是要第一時間解決的問題。函數(shù)式編程是不斷上升的范式,但對于大部分開發(fā)者來說是新奇的。規(guī)模持續(xù)增長的應(yīng) 原文地址:Redux or MobX: An attempt to dissolve the Confusion 原文作者:rwieruch 我在去年大量的使用...

    txgcwm 評論0 收藏0
  • mobx——rudex的簡單替代品

    摘要:是一個的簡單可擴(kuò)展的狀態(tài)管理庫。它的副作用是自動更新。該函數(shù)返回一個值,當(dāng)返回值為的時候,才會繼續(xù)觸發(fā)第一個函數(shù)。當(dāng)返回值為時,不再繼續(xù)監(jiān)聽。包含一個,該值用來區(qū)分執(zhí)行事件的類型。 mobx 能干什么 使用 react 寫小型應(yīng)用,數(shù)據(jù)、業(yè)務(wù)邏輯和視圖的模塊劃分不是很細(xì)是沒有問題的。在這個階段,引入任何狀態(tài)管理庫,都算是奢侈的。但是隨著頁面邏輯的復(fù)雜度提升,在中大型應(yīng)用中,數(shù)據(jù)、業(yè)務(wù)邏...

    DevWiki 評論0 收藏0
  • React 狀態(tài)管理庫: Mobx

    摘要:關(guān)心性能的情況下,需要手動設(shè)置這時就需要引入狀態(tài)管理庫。現(xiàn)在常用的狀態(tài)管理庫有和,本文會重點介紹,然后會將和進(jìn)行對比,最后展望下未來的狀態(tài)管理方面趨勢。如果在任何地方都修改可觀察數(shù)據(jù),將導(dǎo)致頁面狀態(tài)難以管理。 React 是一個專注于視圖層的庫。React 維護(hù)了狀態(tài)到視圖的映射關(guān)系,開發(fā)者只需關(guān)心狀態(tài)即可,由 React 來操控視圖。 在小型應(yīng)用中,單獨使用 React 是沒什么問題...

    liujs 評論0 收藏0
  • 【用故事解讀 MobX源碼(一)】 autorun

    摘要:隨后,執(zhí)行官給出一張當(dāng)張三存款發(fā)生變化之時,此機(jī)構(gòu)的運作時序圖的確,小機(jī)構(gòu)靠人力運作,大機(jī)構(gòu)才靠制度運轉(zhuǎn)。第一條語句創(chuàng)建觀察員第一條語句張三我們調(diào)用的時候,就創(chuàng)建了對象,對象的所有屬性都將被拷貝至一個克隆對象并將克隆對象轉(zhuǎn)變成可觀察的。 ================前言=================== 初衷:網(wǎng)上已有很多關(guān)于 MobX 源碼解讀的文章,但大多閱讀成本甚高。...

    qieangel2013 評論0 收藏0
  • 我為什么從Redux遷移到了Mobx

    摘要:需要注意的是,在中,需要把數(shù)據(jù)聲明為。同時還提供了運行時的類型安全檢查。在利用了,使異步操作可以在一個函數(shù)內(nèi)完成并且可以被追蹤。例如在中,數(shù)組并不是一個,而是一個類的對象,這是為了能監(jiān)聽到數(shù)據(jù)下標(biāo)的賦值。 Redux是一個數(shù)據(jù)管理層,被廣泛用于管理復(fù)雜應(yīng)用的數(shù)據(jù)。但是實際使用中,Redux的表現(xiàn)差強(qiáng)人意,可以說是不好用。而同時,社區(qū)也出現(xiàn)了一些數(shù)據(jù)管理的方案,Mobx就是其中之一。 R...

    DevYK 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<