首頁  >  文章  >  web前端  >  使用store來優化React元件

使用store來優化React元件

小云云
小云云原創
2018-01-04 10:03:061804瀏覽

本文主要介紹了使用store來優化React元件的方法,小編覺得還挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。

在使用 React 編寫元件的時候,我們常常會碰到兩個不同的元件之間需要共享狀態情況,而通常的做法就是提升狀態到父元件。但是這樣做會有一個問題,就是儘管只有兩個元件需要這個狀態,但是因為把狀態提到了父元件,那麼在狀態變化的時候,父元件以及其下面的所有子元件都會重新render,如果你的父組件比較複雜,包含了其他很多子組件的話,就有可能造成效能問題。

Redux 透過把狀態放在全域的store 裡,然後元件去訂閱各自需要的狀態,當狀態改變的時候,只有那些訂閱的狀態改變的元件才重新render,這樣就避免了上面所說的提升狀態所帶來的副作用。但是,當我們在寫一個 React 元件庫的時候,redux 加 react-redux 的組合可能就有點太重了。所以我們可以自己寫一個簡單的 store,來實作類似 Redux 的訂閱模式。

參考Redux 的實作來寫一個簡版的createStore:


#
function createStore(initialState) {
 let state = initialState;
 const listeners = [];

 function setState(partial) {
  state = {
   ...state,
   ...partial,
  };
  for (let i = 0; i < listeners.length; i++) {
   listeners[i]();
  }
 }

 function getState() {
  return state;
 }

 function subscribe(listener) {
  listeners.push(listener);

  return function unsubscribe() {
   const index = listeners.indexOf(listener);
   listeners.splice(index, 1);
  };
 }

 return {
  setState,
  getState,
  subscribe,
 };
}

我們的createStore 很簡單,算上空行也只有33 行,總共暴露了3 個方法,沒有Redux 裡的dispatch 和reducer,直接透過setState 方法改變狀態。下面我們來用它一個計數器的例子。


class Counter extends React.Component {
 constructor(props) {
  super(props);

  // 初始化 store
  this.store = createStore({
   count: 0,
  });
 }

 render() {
  return (
   <p>
    <Buttons store={store} />
    <Result store={store} />
   </p>
  )
 }
}

class Buttons extends React.Component {
 handleClick = (step) => () => {
  const { store } = this.props;
  const { count } = store.getState();
  store.setState({ count: count + step });
 }

 render() {
  return (
   <p>
    <button onClick={this.handleClick(1)}>+</button>
    <button onClick={this.handleClick(1)}>-</button>
   </p>
  );
 }
}

class Result extends React.Component {
 constructor(props) {
  super(props);

  this.state = {
   count: props.store.getState().count,
  };
 }

 componentDidMount() {
  this.props.store.subscribe(() => {
   const { count } = this.props.store.getState();
   if (count !== this.state.count) {
    this.setState({ count });
   }
  });
 }

 render() {
  return (
   <p>{this.state.count}</p>
  );
 };
}

範例中Buttons 裡透過store.setState 來改變store 中的狀態,並不會造成整個Counter 的重新render,但因為Result 中訂閱了store 的變化,所以當count 有變化的時候就可以透過改變自己元件內的狀態來重新render,這樣就巧妙地避免了不必須要的render。

最後,上面的createStore 雖然只有幾十行程式碼,我還是把它寫成了一個叫mini-store 庫放在GitHub 上,並且提供了類似Redux 的Provider 和connect 方法,總共加起來也就100 多行程式碼。如果你也在寫 React 元件庫,需要管理一個複雜元件的狀態,不妨試試這個最佳化方式。

相關推薦:

JS實作點擊網頁判斷是否安裝app並開啟否則跳轉app store

Ecstore取得dbschema內容?

淺談react 同構之樣式直出

以上是使用store來優化React元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn