react組件之間通信

很感謝https://segmentfault.com/u/cwl提供的答案
React 組件間通訊

說 React 組件間通訊之前,我們先來討論一下 React 組件究竟有多少種層級(jí)間的關(guān)系衣形。假設(shè)我們開發(fā)的項(xiàng)目是一個(gè)純 React 的項(xiàng)目五垮,那我們項(xiàng)目應(yīng)該有如下類似的關(guān)系:

父子:Parent 與 Child_1、Child_2捎谨、Child_1_1勒叠、Child_1_2捐韩、Child_2_1

兄弟:Child_1 與 Child_2库继、Child_1_1 與 Child_2、etc.

針對(duì)這些關(guān)系窜醉,我們將來好好討論一下這些關(guān)系間的通訊方式宪萄。

(在 React 中,React 組件之間的關(guān)系為從屬關(guān)系榨惰,與 DOM 元素之間的父子關(guān)系有所不同拜英,下面只是為了說明方便,將 React 組件的關(guān)系類比成父子關(guān)系進(jìn)行闡述)

父組件向子組件通訊

通訊是單向的琅催,數(shù)據(jù)必須是由一方傳到另一方居凶。在 React 中,父組件可以向子組件通過傳 props 的方式藤抡,向子組件進(jìn)行通訊侠碧。

class Parent extends Component{
  state = {
    msg: 'start'
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        msg: 'end'
      });
    }, 1000);
  }

  render() {
    return <Child_1 msg={this.state.msg} />;
  }
}

class Child_1 extends Component{
  render() {
    return <p>{this.props.msg}</p>
  }
}

如果父組件與子組件之間不止一個(gè)層級(jí),如 Parent 與 Child_1_1 這樣的關(guān)系缠黍,可通過 ... 運(yùn)算符(Object 剩余和展開屬性)弄兜,將父組件的信息,以更簡潔的方式傳遞給更深層級(jí)的子組件。通過這種方式替饿,不用考慮性能的問題语泽,通過 babel 轉(zhuǎn)義后的 ... 運(yùn)算符 性能和原生的一致,且上級(jí)組件 props 與 state 的改變视卢,會(huì)導(dǎo)致組件本身及其子組件的生命周期改變踱卵,

// 通過 ... 運(yùn)算符 向 Child_1_1 傳遞 Parent 組件的信息

class Child_1 extends Component{
  render() {
    return <div>
      <p>{this.props.msg}</p>
      <Child_1_1 {...this.props}/>
    </div>
  }
}

class Child_1_1 extends Component{
  render() {
    return <p>{this.props.msg}</p>
  }
}

子組件向父組件通訊

在上一個(gè)例子中,父組件可以通過傳遞 props 的方式据过,自頂而下向子組件進(jìn)行通訊惋砂。而子組件向父組件通訊,同樣也需要父組件向子組件傳遞 props 進(jìn)行通訊蝶俱,只是父組件傳遞的班利,是作用域?yàn)楦附M件自身的函數(shù),子組件調(diào)用該函數(shù)榨呆,將子組件想要傳遞的信息罗标,作為參數(shù),傳遞到父組件的作用域中积蜻。

class Parent extends Component{
  state = {
    msg: 'start'
  };
  
  transferMsg(msg) {
    this.setState({
      msg
    });
  }

  render() {
    return <div>
        <p>child msg: {this.state.msg}</p>
        <Child_1 transferMsg = {msg => this.transferMsg(msg)} />
      </div>;
  }
}

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      this.props.transferMsg('end')
    }, 1000);
  }

  render() {
    return <div>
      <p>child_1 component</p>
    </div>
  }
}

在上面的例子中闯割,我們使用了 箭頭函數(shù),將父組件的 transferMsg 函數(shù)通過 props 傳遞給子組件竿拆,得益于箭頭函數(shù)宙拉,保證子組件在調(diào)用 transferMsg 函數(shù)時(shí),其內(nèi)部 this 仍指向父組件丙笋。

當(dāng)然谢澈,對(duì)于層級(jí)比較深的子組件與父組件之間的通訊,仍可使用 ... 運(yùn)算符御板,將父組件的調(diào)用函數(shù)傳遞給子組件锥忿,具體方法和上面的例子類似。

兄弟組件間通訊

對(duì)于沒有直接關(guān)聯(lián)關(guān)系的兩個(gè)節(jié)點(diǎn)怠肋,就如 Child_1 與 Child_2 之間的關(guān)系敬鬓,他們唯一的關(guān)聯(lián)點(diǎn),就是擁有相同的父組件笙各。參考之前介紹的兩種關(guān)系的通訊方式钉答,如果我們向由 Child_1 向 Child_2 進(jìn)行通訊,我們可以先通過 Child_1 向 Parent 組件進(jìn)行通訊杈抢,再由 Parent 向 Child_2 組件進(jìn)行通訊数尿,所以有以下代碼。

class Parent extends Component{
  state = {
    msg: 'start'
  };

  transferMsg(msg) {
    this.setState({
      msg
    });
  }

  componentDidUpdate() {
    console.log('Parent update');
  }

  render() {
    return (
      <div>
        <Child_1 transferMsg = {msg => this.transferMsg(msg)} />
        <Child_2 msg = {this.state.msg} />
      </div>
    );
  }
}

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      this.props.transferMsg('end')
    }, 1000);
  }

  componentDidUpdate() {
    console.log('Child_1 update');
  }

  render() {
    return <div>
      <p>child_1 component</p>
    </div>
  }
}

class Child_2 extends Component{
  componentDidUpdate() {
    console.log('Child_2 update');
  }

  render() {
    return <div>
      <p>child_2 component: {this.props.msg}</p>
      <Child_2_1 />
    </div>
  }
}

class Child_2_1 extends Component{
  componentDidUpdate() {
    console.log('Child_2_1 update');
  }

  render() {
    return <div>
      <p>child_2_1 component</p>
    </div>
  }
}

然而惶楼,這個(gè)方法有一個(gè)問題砌创,由于 Parent 的 state 發(fā)生變化虏缸,會(huì)觸發(fā) Parent 及從屬于 Parent 的子組件的生命周期,所以我們?cè)诳刂婆_(tái)中可以看到嫩实,在各個(gè)組件中的 componentDidUpdate 方法均被觸發(fā)刽辙。

有沒有更好的解決方式來進(jìn)行兄弟組件間的通訊,甚至是父子組件層級(jí)較深的通訊的呢甲献?

觀察者模式

在傳統(tǒng)的前端解耦方面宰缤,觀察者模式作為比較常見一種設(shè)計(jì)模式,大量使用在各種框架類庫的設(shè)計(jì)當(dāng)中晃洒。即使我們?cè)趯?React慨灭,在寫 JSX,我們核心的部分還是 JavaScript球及。

觀察者模式也叫 發(fā)布者-訂閱者模式氧骤,發(fā)布者發(fā)布事件,訂閱者監(jiān)聽事件并做出反應(yīng)吃引,對(duì)于上面的代碼筹陵,我們引入一個(gè)小模塊,使用觀察者模式進(jìn)行改造镊尺。

import eventProxy from '../eventProxy'

class Parent extends Component{
  render() {
    return (
      <div>
        <Child_1/>
        <Child_2/>
      </div>
    );
  }
}
// componentDidUpdate 與 render 方法與上例一致
class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      // 發(fā)布 msg 事件
      eventProxy.trigger('msg', 'end');
    }, 1000);
  }
}
// componentDidUpdate 方法與上例一致
class Child_2 extends Component{
  state = {
    msg: 'start'
  };

  componentDidMount() {
      // 監(jiān)聽 msg 事件
    eventProxy.on('msg', (msg) => {
      this.setState({
        msg
      });
    });
  }

  render() {
    return <div>
      <p>child_2 component: {this.state.msg}</p>
      <Child_2_1 />
    </div>
  }
}

我們?cè)?child_2 組件的 componentDidMount 中訂閱了 msg 事件朦佩,并在 child_1 componentDidMount 中,在 1s 后發(fā)布了 msg 事件庐氮,child_2 組件對(duì) msg 事件做出相應(yīng)语稠,更新了自身的 state,我們可以看到弄砍,由于在整個(gè)通訊過程中仙畦,只改變了 child_2 的 state,因而只有 child_2 和 child_2_1 出發(fā)了一次更新的生命周期音婶。

而上面代碼中慨畸,神奇的 eventProxy.js 究竟是怎樣的一回事呢?

// eventProxy.js
'use strict';
const eventProxy = {
  onObj: {},
  oneObj: {},
  on: function(key, fn) {
    if(this.onObj[key] === undefined) {
      this.onObj[key] = [];
    }

    this.onObj[key].push(fn);
  },
  one: function(key, fn) {
    if(this.oneObj[key] === undefined) {
      this.oneObj[key] = [];
    }

    this.oneObj[key].push(fn);
  },
  off: function(key) {
    this.onObj[key] = [];
    this.oneObj[key] = [];
  },
  trigger: function() {
    let key, args;
    if(arguments.length == 0) {
      return false;
    }
    key = arguments[0];
    args = [].concat(Array.prototype.slice.call(arguments, 1));

    if(this.onObj[key] !== undefined
      && this.onObj[key].length > 0) {
      for(let i in this.onObj[key]) {
        this.onObj[key][i].apply(null, args);
      }
    }
    if(this.oneObj[key] !== undefined
      && this.oneObj[key].length > 0) {
      for(let i in this.oneObj[key]) {
        this.oneObj[key][i].apply(null, args);
        this.oneObj[key][i] = undefined;
      }
      this.oneObj[key] = [];
    }
  }
};
export default eventProxy;

eventProxy 中桃熄,總共有 on先口、one型奥、off瞳收、trigger 這 4 個(gè)函數(shù):

on、one:on 與 one 函數(shù)用于訂閱者監(jiān)聽相應(yīng)的事件厢汹,并將事件響應(yīng)時(shí)的函數(shù)作為參數(shù)螟深,on 與 one 的唯一區(qū)別就是,使用 one 進(jìn)行訂閱的函數(shù)烫葬,只會(huì)觸發(fā)一次界弧,而 使用 on 進(jìn)行訂閱的函數(shù)凡蜻,每次事件發(fā)生相應(yīng)時(shí)都會(huì)被觸發(fā)。
trigger:trigger 用于發(fā)布者發(fā)布事件垢箕,將除第一參數(shù)(事件名)的其他參數(shù)划栓,作為新的參數(shù),觸發(fā)使用 one 與 on 進(jìn)行訂閱的函數(shù)条获。
off:用于解除所有訂閱了某個(gè)事件的所有函數(shù)忠荞。
Flux 與 Redux

Flux 作為 Facebook 發(fā)布的一種應(yīng)用架構(gòu),他本身是一種模式帅掘,而不是一種框架委煤,基于這個(gè)應(yīng)用架構(gòu)模式,在開源社區(qū)上產(chǎn)生了眾多框架修档,其中最受歡迎的就是我們即將要說的 Redux碧绞。更多關(guān)于 Flux 和 Redux 的介紹這里就不一一展開,有興趣的同學(xué)可以好好看看 Flux 官方介紹吱窝、Flux 架構(gòu)入門教程–阮一峰等相關(guān)資料讥邻。
下面將來好好聊聊 Redux 在組件間通訊的方式。

Flux 需要四大部分組成:Dispatcher癣诱、Stores计维、Views/Controller-Views、Actions撕予,其中的 Views/Controller-Views 可以理解為我們上面所說的 Parent 組件鲫惶,其作用是從 state 當(dāng)中獲取到相應(yīng)的數(shù)據(jù),并將其傳遞給他的子組件(descendants)实抡。而另外 3 個(gè)部分欠母,則是由 Redux 來提供了。

// 該例子主要對(duì)各組件的 componentDidMount 進(jìn)行改造吆寨,其余部分一致

import {createStore} from 'redux'

function reducer(state = {}, action) {
  return action;
}

let store = createStore(reducer);

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      store.dispatch({
        type: 'child_2',
        data: 'hello'
      })
    }, 1000);

    setTimeout(() => {
      store.dispatch({
        type: 'child_2_1',
        data: 'bye'
      })
    }, 2000);
  }
}

class Child_2 extends Component{
  state = {
    msg: 'start'
  };
  
  componentDidUpdate() {
    console.log('Child_2 update', store.getState());
  }

  componentDidMount() {
    store.subscribe(() => {
      let state = store.getState();
      if (state.type === 'child_2') {
        this.setState({
          msg: state.data
        });
      }
    });
  }
}

class Child_2_1 extends Component{
  state = {
    msg: 'start'
  };
    
  componentDidUpdate() {
    console.log('Child_2_1 update', store.getState());
  }


  componentDidMount() {
    store.subscribe(() => {
      let state = store.getState();
      if (state.type === 'child_2_1') {
        this.setState({
          msg: state.data
        });
      }
    });
  }

  render() {
    return <div>
      <p>child_2_1 component: {this.state.msg}</p>
    </div>
  }
}

在上面的例子中赏淌,我們將一個(gè)名為 reducer 的函數(shù)作為參數(shù),生成我們所需要的 store啄清,reducer 接受兩個(gè)參數(shù)六水,一個(gè)是存儲(chǔ)在 store 里面的 state,另一個(gè)是每一次調(diào)用 dispatch 所傳進(jìn)來的 action辣卒。reducer 的作用掷贾,就是對(duì) dispatch 傳進(jìn)來的 action 進(jìn)行處理,并將結(jié)果返回荣茫。而里面的 state 可以通過 store 里面的 getState 方法進(jìn)行獲得想帅,其結(jié)果與最后一次通過 reducer 處理后的結(jié)果保持一致。

在 child_1 組件中啡莉,我們每隔 1s 通過 store 的 dispatch 方法港准,向 store 傳入包含有 type 字段的 action旨剥,reducer 直接將 action 進(jìn)行返回。

而在 child_2 與 child_2_1 組件中浅缸,通過 store 的 subscribe 方法轨帜,監(jiān)聽 store 的變化,觸發(fā) dispatch 后衩椒,所有通過 subscribe 進(jìn)行監(jiān)聽的函數(shù)都會(huì)作出相應(yīng)阵谚,根據(jù)當(dāng)前通過 store.getState() 獲取到的結(jié)果進(jìn)行處理,對(duì)當(dāng)前組件的 state 進(jìn)行設(shè)置烟具。所以我們可以在控制臺(tái)上看到各個(gè)組件更新及存儲(chǔ)在 store 中 state 的情況:

在 Redux 中梢什,store 的作用,與 MVC 中的 Model 類似朝聋,可以將我們項(xiàng)目中的數(shù)據(jù)傳遞給 store嗡午,交給 store 進(jìn)行處理,并可以實(shí)時(shí)通過 store.getState() 獲取到存儲(chǔ)在 store 中的數(shù)據(jù)冀痕。我們對(duì)上面例子的 reducer 及各個(gè)組件的 componentDidMount 做點(diǎn)小修改荔睹,看看 store 的這一個(gè)特性。

import {createStore} from 'redux'

function reducer(state = {}, action) {
  switch (action.type) {
    case 'child_2':
      state.child_2 = action.data + ' child_2';
      return state;
    case 'child_2_1':
      state.child_2_1 = action.data + ' child_2_1';
      return state;
    default:
      return state
  }
}

let store = createStore(reducer);

class Child_1 extends Component{
  componentDidMount() {
    setTimeout(() => {
      store.dispatch({
        type: 'child_2',
        data: 'hello'
      })
    }, 1000);

    setTimeout(() => {
      store.dispatch({
        type: 'child_2_1',
        data: 'bye'
      })
    }, 2000);
  }
}

class Child_2 extends Component{
  componentDidMount() {
    store.subscribe(() => {
      let state = store.getState();

      if (state.hasOwnProperty('child_2')) {
        this.setState({
          msg: state.child_2
        });
      }
    });
  }
}

class Child_2_1 extends Component{
  componentDidMount() {
    store.subscribe(() => {
      let state = store.getState();

      if (state.hasOwnProperty('child_2_1')) {
        this.setState({
          msg: state.child_2_1
        });
      }
    });
  }
}

我們對(duì)創(chuàng)建 store 時(shí)所傳進(jìn)去的 reducer 進(jìn)行修改言蛇。reducer 中僻他,其參數(shù) state 為當(dāng)前 store 的值,我們對(duì)不同的 action 進(jìn)行處理腊尚,并將處理后的結(jié)果存儲(chǔ)在 state 中并進(jìn)行返回吨拗。此時(shí),通過 store.getState() 獲取到的婿斥,就是我們處理完成后的 state劝篷。

Redux 內(nèi)部的實(shí)現(xiàn),其實(shí)也是基于觀察者模式的民宿,reducer 的調(diào)用結(jié)果娇妓,存儲(chǔ)在 store 內(nèi)部的 state 中,并在每一次 reducer 的調(diào)用中并作為參數(shù)傳入活鹰。所以在 child_1 組件第 2s 的 dispatch 后哈恰,child_2 與 child_2_1 組件通過 subscribe 監(jiān)聽的函數(shù),其通過 getState 獲得的值志群,都包含有 child_2 與 child_2_1 字段的着绷,這就是為什么第 2s 后的響應(yīng),child_2 也進(jìn)行了一次生命周期赖舟。所以在對(duì) subscribe 響應(yīng)后的處理蓬戚,最好還是先校對(duì)通過 getState() 獲取到的 state 與當(dāng)前組件的 state 是否相同夸楣。

// child_2
 componentDidMount() {
    store.subscribe(() => {
      let state = store.getState();

      if (state.hasOwnProperty('child_2')
        && state.child_2 !== this.state.msg) {
        this.setState({
          msg: state.child_2
        });
      }
    });
  }

加上這樣的校驗(yàn)宾抓,各個(gè)組件的生命周期的觸發(fā)就符合我們的預(yù)期了子漩。

Redux 對(duì)于組件間的解耦提供了很大的便利,如果你在考慮該不該使用 Redux 的時(shí)候石洗,社區(qū)里有一句話說幢泼,“當(dāng)你不知道該不該使用 Redux 的時(shí)候,那就是不需要的”讲衫。Redux 用起來一時(shí)爽缕棵,重構(gòu)或者將項(xiàng)目留給后人的時(shí)候,就是個(gè)大坑涉兽,Redux 中的 dispatch 和 subscribe 方法遍布代碼的每一個(gè)角落招驴。剛剛的例子不是最好的,F(xiàn)lux 設(shè)計(jì)中的 Controller-Views 概念就是為了解決這個(gè)問題出發(fā)的枷畏,將所有的 subscribe 都置于 Parent 組件(Controller-Views)别厘,由最上層組件控制下層組件的表現(xiàn),然而拥诡,這不就是我們所說的 子組件向父組件通訊 這種方式了触趴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市渴肉,隨后出現(xiàn)的幾起案子冗懦,更是在濱河造成了極大的恐慌,老刑警劉巖仇祭,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件披蕉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡乌奇,警方通過查閱死者的電腦和手機(jī)嚣艇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來华弓,“玉大人食零,你說我怎么就攤上這事〖牌粒” “怎么了贰谣?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長迁霎。 經(jīng)常有香客問我吱抚,道長,這世上最難降的妖魔是什么考廉? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任秘豹,我火速辦了婚禮,結(jié)果婚禮上昌粤,老公的妹妹穿的比我還像新娘既绕。我一直安慰自己啄刹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布凄贩。 她就那樣靜靜地躺著誓军,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疲扎。 梳的紋絲不亂的頭發(fā)上昵时,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音椒丧,去河邊找鬼壹甥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛壶熏,可吹牛的內(nèi)容都是我干的盹廷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼久橙,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼俄占!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起淆衷,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤缸榄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后祝拯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甚带,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年佳头,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹰贵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡康嘉,死狀恐怖碉输,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亭珍,我是刑警寧澤敷钾,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站肄梨,受9級(jí)特大地震影響阻荒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜众羡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一侨赡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦羊壹、人聲如沸蓖宦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尔店,卻和暖如春眨攘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嚣州。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工鲫售, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人该肴。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓情竹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匀哄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秦效,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 今天來看一下react組件之間是怎么進(jìn)行通訊的。react推崇的是單向數(shù)據(jù)流涎嚼,自上而下進(jìn)行數(shù)據(jù)的傳遞阱州,但是由下而上...
    親親qin閱讀 5,997評(píng)論 2 12
  • 做React需要會(huì)什么苔货? react的功能其實(shí)很單一,主要負(fù)責(zé)渲染的功能立哑,現(xiàn)有的框架夜惭,比如angular是一個(gè)大而...
    蒼都閱讀 14,740評(píng)論 1 139
  • 學(xué)習(xí)必備要點(diǎn): 首先弄明白,Redux在使用React開發(fā)應(yīng)用時(shí)铛绰,起到什么作用——狀態(tài)集中管理 弄清楚Redux是...
    賀賀v5閱讀 8,877評(píng)論 10 58
  • 晚安捂掰,心 晚安若皱,你們 晚安,螢火蟲 晚安尘颓,星辰大海 晚安走触,街角的喧囂 晚安,還未安歇的你 晚安疤苹,不斷循環(huán)的回憶 晚...
    boyzcl閱讀 226評(píng)論 0 2
  • 2018年目標(biāo)如下: 1貴州自駕遊 2最少一到三個(gè)月休息 3學(xué)瑜伽 4自學(xué)鋼琴互广,起碼會(huì)彈幾曲拿手的。 5雲(yún)之南端....
    wenwen7446閱讀 133評(píng)論 0 0