中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Context-React如何跨組件訪問數據

發布時間:2021-12-03 11:45:26 來源:億速云 閱讀:258 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關Context-React如何跨組件訪問數據的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。


  Context提供了一種跨組件訪問數據的方法。它無需在組件樹間逐層傳遞屬性,也可以方便的訪問其他組件的數據
  在經典的React應用中,數據是父組件通過props向子組件傳遞的。但是在某些特定場合,有些數據需要在各個組件之間共享。Context為我們提供一種組件之間共享數據的方式,可以避免數據在組件樹上逐層傳遞
  使用Context的場合
Context可以在組件樹的組件之間共享“全局”數據。例如:登陸的用戶信息,用戶選擇的主題、語言等等。下面的例子中,我們“手動”自上而下傳遞theme屬性,用來設定Button的樣式。
class App extends React.Component {
render() {
return <Toolbar theme="dark"></Toolbar>;
}
}
function Toolbar(props) {
// The Toolbar component must take an extra "theme" prop
// and pass it to the ThemedButton. This can become painful
// if every single button in the app needs to know the theme
// because it would have to be passed through all components.
return (
<div>
<ThemedButton theme={props.theme}></ThemedButton>
</div>
);
}
class ThemedButton extends React.Component {
render() {
return <Button theme={this.props.theme}></Button>;
}
}
使用Context,我們可以避免通過多個中間組件傳遞props
// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Use a Provider to pass the current theme to the tree below.
// Any component can read it, no matter how deep it is.
// In this example, we're passing "dark" as the current value.
return (
<ThemeContext.Provider value="dark">
<Toolbar></Toolbar>
</ThemeContext.Provider>
);
}
}

// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}

class ThemedButton extends React.Component {
// Assign a contextType to read the current theme context.
// React will find the closest theme Provider above and use its value.
// In this example, the current theme is "dark".
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
有時候,有些數據需要被很多組件訪問,而且這些組件在組件樹的不同層上。Context可以使我們以“廣播”的形式,在各個組件中共享數據的改變
Context相關API
React.createContext
const MyContext = React.createContext(defaultValue);復制代碼
創建一個新的Context對象。當React渲染一個組件,且該組件注冊了Context時,它將讀取父組件中,距離該組件最近的Provider組件的Context值
defaultValue只有在“Consumer”組件找不到Provider組件時,才會被使用。
Context.Provider
<MyContext.Provider value={/ some value /}>復制代碼
每個Context對象都攜帶一個名叫Provider的React組件。Provider可以使得“Consumer”組件監聽context的變更
通過向Provider的后代Consumer組件傳遞value的prop,一個Provider可以與多個Consumer組件建立聯系。
所有的后代Consumer組件在Provider的value屬性更新后,都會被重新渲染。這個更新從Provider到其后代Consumer組件之間傳播,但是并不會觸發shouldComponentUpdate方法。所以即使Consumer組件的祖先組件沒有更新,Consumer組件也會更新
Context使用與Object.is相同的算法來對比value的新、舊值,以判定其value是否被更新了
注意
當向value傳遞對象時,這種判定value是否改變的方式可能會引起問題。
Class.contextType
class MyClass extends React.Component {
componentDidMount() {
let value = this.context;
/ perform a side-effect at mount using the value of MyContext /
}
componentDidUpdate() {
let value = this.context;
/ ... /
}
componentWillUnmount() {
let value = this.context;
/ ... /
}
render() {
let value = this.context;
/ render something based on the value of MyContext /
}
}
MyClass.contextType = MyContext;
為class的contextTpe屬性賦值一個Context對象后,我們可以通過this.context在組件的各個聲明周期函數中獲取到當前的Context對象的方法
注意:
通過這種方式,每個組件只能注冊一個context對象。如果需要讀取多個context的value值
如果編碼中使用了ES實驗中的語法,那么可以使用類的靜態(static)成員來初始化contextTYpe.代碼如下:
class MyClass extends React.Component {
static contextType = MyContext;
render() {
let value = this.context;
/ render something based on the value /
}
}
Context.Consumer
<MyContext.Consumer>
{value => / render something based on the context value /}
</MyContext.Consumer>
Consumer是一個監聽context變化的React組件。它使得我們可以在一個函數組件中,監聽contxt的改變。
Consumer組件要求其子元素為一個函數。該函數的參數接收當前的context的value值,要求返回一個React節點(node) 傳遞給該函數的參數value等于距離此Consumner最近的外層Provider組件的context值。如果沒有外層的Provider組件,則等于調用createContext()時傳遞的參數值(context的默認值)。
注意
更多關于“子元素為一個函數”的信息
栗子
在嵌套組件中更新Context
開發中,我們經常需要在某些嵌套結構很深的組件上更新context的value值。此時,我們可以向下傳遞一個函數,用它來更新context的value。代碼如下:
theme-context.js
// Make sure the shape of the default value passed to// createContext matches the shape that the consumers expect!export const ThemeContext = React.createContext({
theme: themes.dark,
toggleTheme: () => {},
});
theme-toggler-button.js
import {ThemeContext} from './theme-context';
function ThemeTogglerButton() {
// The Theme Toggler Button receives not only the theme
// but also a toggleTheme function from the context
return (
<ThemeContext.Consumer>
{({theme, toggleTheme}) => (
<button
onClick={toggleTheme}
style={{backgroundColor: theme.background}}>
Toggle Theme
</button>
)}
</ThemeContext.Consumer>
);
}

export default ThemeTogglerButton;
app.js
import {ThemeContext, themes} from './theme-context';import ThemeTogglerButton from './theme-toggler-button';
class App extends React.Component {
constructor(props) {
super(props);

this.toggleTheme = () => {
  this.setState(state => ({
    theme:
      state.theme === themes.dark
        ? themes.light
        : themes.dark,
  }));
};

// State also contains the updater function so it will
// be passed down into the context provider
this.state = {
  theme: themes.light,
  toggleTheme: this.toggleTheme,
};

}

render() {
// The entire state is passed to the provider
return (
<ThemeContext.Provider value={this.state}>
<Content />
</ThemeContext.Provider>
);
}
}

function Content() {
return (
<div>
<ThemeTogglerButton />
</div>
);
}

ReactDOM.render(<App />, document.root);
使用多個Contexts
為了保持React的快速渲染,我們需要將每個consumer組件編寫成一個獨立的組件節點(node)
// Theme context, default to light themeconst ThemeContext = React.createContext('light');
// Signed-in user contextconst UserContext = React.createContext({
name: 'Guest',
});
class App extends React.Component {
render() {
const {signedInUser, theme} = this.props;

// App component that provides initial context values
return (
  <ThemeContext.Provider value={theme}>
    <UserContext.Provider value={signedInUser}>
      <Layout />
    </UserContext.Provider>
  </ThemeContext.Provider>
);

}
}

function Layout() {
return (
<div>
<Sidebar />
<Content />
</div>
);
}

// A component may consume multiple contexts
function Content() {
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
如果有兩個以上的context經常一起使用,我們需要考慮創建一個render prop component一并提供兩個Context
注意
因為context使用引用標示符(reference identity)來判斷何時需要重新渲染,所以有些情況下,當provider的父元素重新渲染時,會觸發consumer的非內部渲染。例如下面代碼,在每次Provider重新渲染時,會重新渲染所有的consumer組件。因為會一直創建一個新的對象賦值給value(value一直在變)
class App extends React.Component {
render() {
return (
<Provider value={{something: 'something'}}>
<Toolbar />
</Provider>
);
}
}
為了避免這個問題,可以將value放在組件的state中
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: {something: 'something'},
};
}

render() {
return (
<Provider value={this.state.value}>
<Toolbar />
</Provider>
);
}
}

感謝各位的閱讀!關于“Context-React如何跨組件訪問數據”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广安市| 随州市| 葫芦岛市| 正蓝旗| 塘沽区| 南充市| 尚志市| 炉霍县| 依安县| 全州县| 沈丘县| 绥阳县| 宁晋县| 新巴尔虎右旗| 洛南县| 北辰区| 娱乐| 都匀市| 阳信县| 安化县| 龙口市| 和龙市| 孙吴县| 资讯| 天镇县| 三穗县| 苍山县| 乌审旗| 大英县| 齐齐哈尔市| 朔州市| 昌宁县| 杨浦区| 新邵县| 手游| 松滋市| 延边| 怀远县| 陇川县| 望奎县| 东海县|