redux5 - 實現 react-redux 前置技能之 react庫的context的使用

參考redux倉庫的src目錄,初步手寫實現了以下3個方法


  • createStore() : 創建數據倉庫,導出了3個方法(dispacth,subscribe,getState)
  • combineReducers():合併多個小的reducer,傳入一個對象
  • bindActionCreators() : 簡化代碼 api,把所有的action存入一個對象,和dispacth,一塊傳入此方法中 就不用再到處手動調用 dispatch

還剩下幾個,先不說了,然而,就這麼幾行代碼,已經基本讓項目配合這些代碼跑起來一個數據倉庫了,然而,它還是有很多的冗餘代碼,比如在 react 項目中,還是需要每個文件 引入好多額外的redux 的東西, 所以,開發中還會結合 react-redux 一塊使用,這樣就只操作 props 了, 也是開發者比較熟悉的 react 的語法,關於 react-redux 的實現,參考倉庫源碼,發現,它就是使用了 react 的 context 這個api,實現的自上而下的跨組件通信

參考文檔context一節

使用context幾個步驟

  1. 創建上下文對象,導出一個對象,該對象又導出倆組件
// createContext() 接收一個參數,作爲默認狀態值
const Context = React.createContext(null);
// 提供倆組件
let { Provider, Consumer } = Context;
  1. 使用上下文對象導出的組件
  • Provider: 提供者,默認頂級父組件, 有一個默認寫死的屬性 value,並且只能通過value屬性向下傳值
  • Consumer: 消費者, 用於子組件從父組件取值

代碼效果演示

  1. 父組件, 提供數據,供子組件消費
// ... 略
class App extends Component {
  render() {
    let value = 'hello';
    return (
      <Provider value={value}>
        <div style={{ border: '2px solid #950', padding: 5 }}>
          <p>我是父組件的默認值:{value}</p>
          <AChild />
          <CChild />
          <BChild />
        </div>
      </Provider>
    );
  }
}
  1. 子組件獲取父組件向下傳的的數據,
class AChild extends Component {
  render() {
    return (
      <Consumer>
        {(value) => (
          <div style={{ border: '3px solid #400', margin: 5 }}>
            <p>我是(類組件)子組件A</p>
            <span>我接收的值:{value}</span>
          </div>
        )}
      </Consumer>
    );
  }
}
  1. 類組件還可以使用this.context()語法獲取
// 子組件3(類組件)
class CChild extends Component {
  static contextType = Context;
  render() {
    return (
      <div style={{ border: '2px solid #200', margin: 5 }}>
        <p>我是(類組件)子組件C</p>
        <span>我接收的值:{this.context}</span>
      </div>
    );
  }
}
  1. 函數組件只能使用Consumer獲取數據
function BChild() {
  return (
    <Consumer>
      {(value) => {
        return (
          <div style={{ border: '2px solid #f90', margin: 5 }}>
            <p>我是(函數組件)子組件B</p>
            <span>我接收的值:{value}</span>
          </div>
        );
      }}
    </Consumer>
  );
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章