react-redux?mobx?或許我須要更加小巧玲瓏的

前戲

前端主流開發框架,react,vue,angular三分天下各執己見,隨意一點火星便能引起框架大戰,可是框架選擇主觀性自己就很強,所以這裏就不評說了,一較高下不是幾句話說得清的,我我的比較喜歡react,也只是由於其餘的我用的很少,也許只是先入爲主那麼簡單。react帶給咱們的顛覆我在這裏就不班門弄斧了,大神們已經講太多了。雖然react好用,不過始終是個基礎框架,react最大的亮點在於它的狀態管理,然鵝,使用原生react最大的不爽也是在於狀態管理。使用原生react容易形成狀態管理混亂的問題,爲了解決這個問題,後來FB提出flux的思想,慢慢發展出redux,以及成熟的react-redux和mobx。我的認爲react-redux很成熟很好用,有些缺點可是並不傷大雅,mobx以不一樣的思路來解決這個問題,並且比react-redux更加小巧一點,也不錯。不過,有時候成熟度越高,也就意味着限制越多,一些龐大的項目因爲自己項目的複雜性,再引入react-redux卻是很合適,可是當咱們的項目沒有大到使用react-redux這些框架,一旦引入這類框架就會發現,我其實只想要讓你管管個人狀態,但你管的太寬了,全部的路徑都給我規劃完了,好比我在客廳,須要喊一聲在臥室的老婆,我本來只是想喊一嗓子就行了,結果你也讓我打個電話,殺雞用牛刀我不反對,不過你這把刀太沉了,反而影響了個人效率這就不合適了吧。好吧,react-reudx&mobx,拜拜,咱們真的不合適。html

激情

既然不合適,那咱們只能另覓新歡了,從react出發,或許咱們能夠本身倒騰一個簡單可用的狀態管理框架呢。那麼咱們來分析一下咱們最大的需求是什麼呢,react原生狀態管理最大的問題在哪呢?就是任意兩個組件之間通訊的問題,我須要的是兩個組件之間的通訊,是絕密的,不須要中間任何節點的感知。這固然有辦法,利用事件機制嘛,好吧,咱們此次稍微不那麼low一點,既然是react的套餐,那仍是要稍微要點血緣關係的。那究竟怎麼搞?咱們先來整理一下思路,其實這個思路能夠參考一下flux,redux的設計,咱們也須要一箇中央數據中心store,對咱們的數據進行集中式管理,任意節點之間的通訊其實都是經過這個store進行的。那具體如何作,讓咱們迴歸本質,react的通訊是如何體現的,是由某個節點發起的某個動做致使狀態變化,而後該狀態變化同步到UI的變化,因此歸根結底,就是這個簡單的公式,store->UI。任意節點狀態的變化,映射到中央數據管理中心store,由store進行廣播出去,這就是實現了最簡單的中心化狀態管理。舉個簡單的栗子來進行說明。前端

舉個栗子

我定義了一個store,就是個管理state的對象,裏面有個bindContext方法,每次裝載組件的時候會把組件對象實例裝入數組contexts,setState方法其實就是將每個組件分別調用一次setState。而後我定義了一個App組件,裏面掛載Module1和Module2兩個組件,Module2下掛載一個SubModule21的子組件。當我每次須要組件之間通訊,好比SubModule21中點擊「清空Module1的值」按鈕,這個就是SubModule21與Module1組件之間的通訊,其實Module1並無感知到是誰在對它進行操做,咱們更新的實際上是store中的數據狀態,並由它統一下發到組件。代碼以下:
index.html代碼:vue

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>測試</title>
</head>
<body>
<div id="page-container"></div>
</body>
</html>複製代碼
import React from 'react';
import ReactDOM from 'react-dom';

/**
 * 統一狀態管理對象
 */
let store = {
    //目標組件對象
    contexts: [],
    //state數據
    state: {

    },
    //註冊綁定組件與狀態數據,用於setState
    bindContext(_context) {
        this.contexts.push(_context);
        return this.state;
    },
    setState(bs_state, context) {
        this.contexts.map((item) => {
            React.Component.prototype.setState.call(item, bs_state);
        })

    }
}

/**
 * 入口組件
 */
class App extends React.Component {
    constructor() {
        super();
        store.bindContext(this);
    }
    render() {
        return ( < div >
            < Module1 / >
            < Module2 / >
            < /div>
        )
    }
}

/**
 * siblings1
 */
class Module1 extends React.Component {
    constructor() {
        super();
        this.state = Object.assign({}, store.bindContext(this));
    }
    render() {
        return ( < div >
            < p > -- -- -- --Module1-- -- -- -- - < /p> < input type = "number"
            value = {
                this.state.m1Var
            }
            onChange = {
                this.setValue
            }
            /> < /div>
        )
    }
    setValue(e) {
        console.log(e.target.value);
        store.setState({
            m1Var: e.target.value
        })
    }
}

/**
 * siblings2
 */
class Module2 extends React.Component {
    constructor() {
        super();
        this.state = Object.assign({}, store.bindContext(this));
    }
    render() {
        return ( < div >
            < p > -- -- -- -- - Module2-- -- -- -- - < /p>
            兄弟節點Module1的值: {
                this.state.m1Var
            } < SubModule21 / >
            < /div>
        )
    }
}

/**
 * Module2的子組件
 */
class SubModule21 extends React.Component {
    constructor() {
        super();
        this.state = Object.assign({}, store.bindContext(this));
    }
    render() {
        return ( < div >
            < p > -- -- -- - SubModule21-- -- -- -- < /p> < button onClick = {
                this.clean
            } > 清空Module1的值 < /button> < /div>
        )
    }
    clean() {
        store.setState({
            m1Var: ""
        })
    }
}


ReactDOM.render( < App / > , document.getElementById("page-container"));複製代碼

不知道並你們注意到沒有,這個思路必定程度上是逆react開發的,由於即便是父子組件之間,實際上是沒有經過props進行聯繫的,都是統一使用setState來進行數據的下發,幾乎拋棄了props。彷佛是有點問題,可是細細想來實際上是沒有問題的,由於react本來就是數據驅動的,setState和props只是不一樣場景下傳遞數據的方式罷了,不一樣的設計思路,只是方式就會有所區別。核心,仍是在於狀態數據的變化。react

高潮

本篇只是將其中的核心思想進行簡單的呈現,相信你們會發現這段代碼存在不少的問題,很明顯store對象存在部分邏輯問題,細細分析會發現一些亟需優化的點,而且大量存在bindContext這樣的樣板代碼十分不優雅,不過這並不影響咱們呈現核心思想。固然只有核心思想仍是不夠的,須要進行繼續完善,最終的目的是完成一個簡約卻五臟俱全的框架。
好吧,此次高潮有點短暫。。。redux

結語

或許這個算不上一個真正的框架,多是個非主流的玩意兒,但會讓咱們在不須要redux或者mobx的時候多一種選擇。優秀的框架有不少不少,但咱們不能一直只是當個使用者,咱們須要一同參與建設,即便最後出來的玩意可能只有咱們本身使用,這個思想或許沒人認同,那又何妨,咱們知道咱們比創造出這玩意以前的咱們更加牛逼了。我會盡可能使用react原生提供的一些特性來完成,或許能夠從中發現更多react中未曾關注到的點。我相信,技術,是須要多玩玩的。數組

歡迎拍磚!!!bash

相關文章
相關標籤/搜索