vue provide 和 react provider

vue provide/inject

作用:祖先組件向其所有子孫后代傳值

這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時(shí)間里始終生效。

provide 選項(xiàng)應(yīng)該是一個(gè)對(duì)象或返回一個(gè)對(duì)象的函數(shù)。該對(duì)象包含可注入其子孫的 property。在該對(duì)象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 SymbolReflect.ownKeys 的環(huán)境下可工作。

inject 選項(xiàng)應(yīng)該是:

  • 一個(gè)字符串?dāng)?shù)組,或
  • 一個(gè)對(duì)象,對(duì)象的 key 是本地的綁定名,value 是:
    • 在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol),或
    • 一個(gè)對(duì)象,該對(duì)象的:
      • from property 是在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol)
      • default property 是降級(jí)情況下使用的 value

提示:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽的對(duì)象,那么其對(duì)象的 property 還是可響應(yīng)的。

// 父級(jí)組件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 子組件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

react Context

作用: Context 提供了一個(gè)無需為每層組件手動(dòng)添加 props,就能在組件樹間進(jìn)行數(shù)據(jù)傳遞的方法。

在一個(gè)典型的 React 應(yīng)用中,數(shù)據(jù)是通過 props 屬性自上而下(由父及子)進(jìn)行傳遞的,但這種做法對(duì)于某些類型的屬性而言是極其繁瑣的(例如:地區(qū)偏好,UI 主題),這些屬性是應(yīng)用程序中許多組件都需要的。Context 提供了一種在組件之間共享此類值的方式,而不必顯式地通過組件樹的逐層傳遞 props。

如果你只是想避免層層傳遞一些屬性,組件組合(component composition)有時(shí)候是一個(gè)比 context 更好的解決方案。

  1. 創(chuàng)建一個(gè) Context 對(duì)象
const MyContext = React.createContext(defaultValue);

只有當(dāng)組件所處的樹中沒有匹配到 Provider 時(shí),其 defaultValue 參數(shù)才會(huì)生效。這有助于在不使用 Provider 包裝組件的情況下對(duì)組件進(jìn)行測(cè)試。

  1. Context.Provider組件
<MyContext.Provider value={/* 某個(gè)值 */}>

每個(gè) Context 對(duì)象都會(huì)返回一個(gè) Provider React 組件,它允許消費(fèi)組件訂閱 context 的變化。

Provider 接收一個(gè) value 屬性,傳遞給消費(fèi)組件。

當(dāng) Provider 的 value 值發(fā)生變化時(shí),它內(nèi)部的所有消費(fèi)組件都會(huì)重新渲染。Provider 及其內(nèi)部 consumer 組件都不受制于 shouldComponentUpdate 函數(shù),因此當(dāng) consumer 組件在其祖先組件退出更新的情況下也能更新。

  1. Context.Consumer 訂閱到 context 變更
<MyContext.Consumer>
  {value => /* 基于 context 值進(jìn)行渲染*/}
</MyContext.Consumer>

這里,React 組件也可以訂閱到 context 變更。這能讓你在函數(shù)式組件中完成訂閱 context。

這需要函數(shù)作為子元素(function as a child)這種做法。這個(gè)函數(shù)接收當(dāng)前的 context 值,返回一個(gè) React 節(jié)點(diǎn)。傳遞給函數(shù)的 value 值等同于往上組件樹離這個(gè) context 最近的 Provider 提供的 value 值。如果沒有對(duì)應(yīng)的 Provider,value 參數(shù)等同于傳遞給 createContext()defaultValue。

// Context 可以讓我們無須明確地傳遍每一個(gè)組件,就能將值深入傳遞進(jìn)組件樹。
// 為當(dāng)前的 theme 創(chuàng)建一個(gè) context(“l(fā)ight”為默認(rèn)值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // 使用一個(gè) Provider 來將當(dāng)前的 theme 傳遞給以下的組件樹。
    // 無論多深,任何組件都能讀取這個(gè)值。
    // 在這個(gè)例子中,我們將 “dark” 作為當(dāng)前的值傳遞下去。
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 中間的組件再也不必指明往下傳遞 theme 了。
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 指定 contextType 讀取當(dāng)前的 theme context。
  // React 會(huì)往上找到最近的 theme Provider,然后使用它的值。
  // 在這個(gè)例子中,當(dāng)前的 theme 值為 “dark”。
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
}

react hooks useContext

const value = useContext(MyContext);

接收一個(gè) context 對(duì)象(React.createContext 的返回值)并返回該 context 的當(dāng)前值。當(dāng)前的 context 值由上層組件中距離當(dāng)前組件最近的 <MyContext.Provider> 的 value prop 決定。
useContext 的參數(shù)必須是 context 對(duì)象本身

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

參考:https://www.cnblogs.com/vs1435/p/12983700.html
https://cn.vuejs.org/v2/api/#provide-inject
https://react.docschina.org/docs/context.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容