iamsiutw / daily_note

Blog/Daily Note
1 stars 0 forks source link

20190313 #26

Open iamsiutw opened 5 years ago

iamsiutw commented 5 years ago

日期: 2019/3/13 WED

目標: 26/30


Context API

Context API 的核心概念,在昨天的日記有約略說明,原定週末要寫篇完整的筆記,改變計畫今天就動筆吧。

參考官方文件寫了一個簡單的程式如下:

App.js

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (      
        <Toolbar theme="dark" />
  }
}

const Toolbar = props => {
  return (    
      <ThemedButton theme={props.theme} />
  );
}

class ThemedButton extends Component {
  render() {
    return (      
        <Button theme={this.props.theme} />      
    )
  }
}

const Button = props => {
  return (
    <div>Theme: {props.theme}</div>
  )
}

export default App;

程式結構圖大概長這樣:

最內層的 Button 如果要拿到在 App 定義的 theme,必須藉由傳入 prop 參數,一層一層的傳遞到 Button 才能達到目的。

建立一個全域的 Context 給整個 DOM Tree 使用會使比較理想的做法,實作如下:

import React, { Component, useContext } from 'react';

const ThemeContext = React.createContext('light'); 
// 建立 context

class App extends Component {
  render() {
    return (
    // 建立一個 provider tag 把最上層的 component 包起來
    // 如此內部所有的 child component 都能取得 value
      <ThemeContext.Provider value='dark'>
        <Toolbar/>
      </ThemeContext.Provider>
    )
  }
}

const Toolbar = props => {
  return (    
      <ThemedButton />
  );
}

class ThemedButton extends Component {

  static contextType = ThemeContext;
  // 在 class based component 建立 static contextType
  // 這個是 React.Component 內部即有定義的屬性
  render() {
    return (      
        <Button theme={this.context} /> 
        // 使用 this.context 取得 context value
    )
  }
}

const Button = props => {
  const theme = useContext(ThemeContext);
  // functional component 沒有 static contextType 可以使用
  // 可改用 useContext() Hook 來取得 ThemeContext
  return (
    <div>
      <div>Theme, use useContext: {theme}</div>      
      <div>Theme, use props: {props.theme}</div>
    </div>
  );
}

export default App;

See, it's much clear than props chain, right?

隨筆

連續 30 天的日記挑戰進入倒數囉,能夠堅持到現在真的該給自己一個掌聲。

React 的學習也進入下一個階段,持續加油吧!