使用 React 的 Context API 來管理數據

Redux 以外的選擇

事實上大型應用搭配 Redux 幫助管理複雜的數據流是比較好的選擇, 但若是中小型應用想要擺脫 Redux 較多的概念與固定的模板語法, 咱們也有新的選擇: React V16 版本推出了新版的 Context API, 能夠幫助咱們使用較低的成本快速管理數據流.react

對於 Context 的理解

Context 具備跨級提供數據的特性, 可以以一種相似總線的思想把數據全局共享. 於是對於較多須要全局共享的數據, 若是顏色主題 (Theme)、語言文案(i18n)、賬號數據(Account)、服務配置(Service Config)等, 經過 Context 來進行管理, 能夠很方即是地在任意一個組件中使用共享的數據,而無需使用 localStorage 頻繁讀取, 或是 從根組件逐級傳遞到目標組件redux

基本 API

  • 建立數據源
// Context.js
import React from 'react';
// 初始化的數據源, 參數能夠不指定, 也能夠是 String|Boolean|Number|Object|Array
const Context = React.createContext('inital Data');
export { Context };
// 生成的context對象具備兩個組件類對象
const { Provider, Consumer } = Context;
  • 包裹根組件
import React from 'react';
import ReactDOM from 'react-dom';
import { Context } from './Context.js';

// 生成的數據源對象提供了 Provider 成員, 意思是數據源的提供者, value 屬性的值即爲[全局傳遞使用的數據]
// 包裹 App 根組件
ReactDOM.render(
    <Context.Provider value={'this is real inital data!'}>
        <App />
    </Context.Provider>,
    document.getElementById('root')
); // 使用 Context 提供的 Provider 注入(提供)數據
  • 在做意組件中使用數據
import React from 'react';
import { Context } from './Context.js';
export class Page extends Component {
    render() {
        return (
            <Context.Consumer>
                {context => {
                    return context;
                }}
            </Context.Consumer> // 使用 Context 提供的 Consumer 使用(消費)數據, 最後渲染出 this is real inital data!文本節點
        );
    }
}

實戰使用

// Context.js 在 Context.js 中初始化 Context
  import React from 'react';
  const Context = React.createContext('hello mobx'); // 傳入初始化的參數 'hello mobx', 能夠是字符串|數字|對象
  export { Context };

  // App.js 根組件
  import React from 'react';
  import ReactDOM from 'react-dom';
  import { Context } from './Context';

  ReactDOM.render(
    <Context.Provider value={'hello redux'}>
      <RootApp />
    </Context.Provider>
  , document.getElementById('root')); // 使用 Context 提供的 Provider 注入(提供)數據

  // index.js 首頁
  import React, { Component } from 'react';
  import { Context } from './Context';

  export default IndexPage extends Component {
    render() {
      return (
        <Context.Consumer>
          { context => {
            return <Span>{ context }</Span>
          }}
        </Context.Consumer> // 使用 Context 提供的 Consumer 使用(消費)數據
      )
    }
  }

使用感覺

Context.Consumer 組件的寫法必須寫成回調函數形式, 不利於代碼閱讀與理解, 全部使用到數據的組件都須要手動包裹、綁定。對於現有應用,存在必定改形成本,對於中小型應用也不想加入 Redux 進行數據管理的應用, 也是挺友好的dom

相關文章
相關標籤/搜索