您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“react中context傳值和生命周期源碼分析”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“react中context傳值和生命周期源碼分析”吧!
假設(shè):
項(xiàng)目中存在復(fù)雜組件樹(shù):
數(shù)據(jù)是通過(guò) props 屬性自上而下(由父及子)進(jìn)行傳遞的,但這種做法對(duì)于某些類(lèi)型的屬性而言是極其繁瑣的(例如:地區(qū)偏好,UI 主題),這些屬性是應(yīng)用程序中許多組件都需要的。
Context 提供了一種在組件之間共享此類(lèi)值的方式,而不必顯式地通過(guò)組件樹(shù)的逐層傳遞 props。
Context 設(shè)計(jì)目的是為了共享那些對(duì)于一個(gè)組件樹(shù)而言是“全局”的數(shù)據(jù),例如當(dāng)前認(rèn)證的用戶(hù)、主題或首選語(yǔ)言。
1.React.createContext API 功能: 創(chuàng)建一個(gè) Context 對(duì)象。 //代碼 //創(chuàng)建context對(duì)象的 import React from 'react' let context=React.createContext(); export default context; 2.Context.Provider API 功能: Provider 是context對(duì)象提供的內(nèi)置組件 限定在某個(gè)作用域中使用context傳值。 限定作用域傳值。 3.Context.Consumer context對(duì)象的內(nèi)置組件 <MyContext.Consumer> {value => /* 基于 context 值進(jìn)行渲染*/} </MyContext.Consumer> 作用:監(jiān)聽(tīng)訂閱的context變更, 這個(gè)函數(shù)接收當(dāng)前的 context 值,返回一個(gè) React 節(jié)點(diǎn)。
1.創(chuàng)建context.js文件 創(chuàng)建context對(duì)象 用來(lái)做context傳值。 //創(chuàng)建context對(duì)象的 import React from 'react' export default React.createContext();
2。使用context找到限定范圍使用內(nèi)置組件Provider {/* 使用Provider 內(nèi)置組件限定context范圍 */} {/* value 必填 context傳遞的值 */} <ThemeContext.Provider> <div className="Admin"> <div className="LeftMenu"> <LeftMenu></LeftMenu> </div> <div className="RightContent"> <div className="RightContent-top"> <TopHeader></TopHeader> </div> <div className="RightContent-bottom"> <Dashborder></Dashborder> </div> </div> </ThemeContext.Provider>
瀏覽器報(bào)錯(cuò):
3.在使用context的組件中進(jìn)行訂閱 左側(cè)菜單組件 import React, { Component } from "react"; console.log(Component); //引入context對(duì)象 import ThemeContext from "../components/context"; class LeftMenu extends Component { constructor(props) { super(props); this.state = {}; } render() { return ( <> <div>左側(cè)菜單</div> </> ); } } //class類(lèi)組件存在contextType 綁定context對(duì)象 LeftMenu.contextType = ThemeContext;
組件中綁定context之后使用:
意味著訂閱context組件的內(nèi)部使用this.context獲取。
render() { //獲取context let theme = this.context; return ( <> <div className={theme}>左側(cè)菜單</div> </> ); }
固定主體修改為動(dòng)態(tài)主體
修改了context文件代碼 //定義默認(rèn)主體色 export const themes = { dark: { backgroundColor: "#000", color: "#fff", }, light: { backgroundColor: "#fff", color: "#000", }, }; //創(chuàng)建context對(duì)象的 import React from "react"; export const ThemeContext = React.createContext();
app.js文件中獲取主題,動(dòng)態(tài)切換主題。使用主題變量 constructor(props) { super(props); this.state = { //將固定的主體設(shè)置為state狀態(tài) themeType: "dark",//控制主體切換 nowTheme: themes["dark"],//獲取當(dāng)前默認(rèn)主體 }; } render() { //解構(gòu)獲取 let { nowTheme } = this.state; return ( <> {/* 使用Provider 內(nèi)置組件限定context范圍 */} {/* value 必填 context傳遞的值 */} <ThemeContext.Provider value={nowTheme}>
訂閱組件中使用this.context獲取訂閱
render() { //獲取context let { backgroundColor, color } = this.context; return ( <> //直接綁定行內(nèi)css <div style={{ backgroundColor: backgroundColor, color: color }}> 左側(cè)菜單 </div> </> ); }
用戶(hù)點(diǎn)擊其他組件修改主題的按鈕來(lái)變更主題
注意:不能直接使用this.context修改變量值 //可以在provider組件上 value中攜帶修改函數(shù)傳遞。在訂閱組件中獲取修改方法,執(zhí)行反向傳遞值。 //修改主題變量方法 changeTheme(type) { console.log("測(cè)試", type); this.setState({ themeType: type, nowTheme: themes[type] }); } render() { //解構(gòu)獲取 let { nowTheme } = this.state; return ( <> {/* 使用Provider 內(nèi)置組件限定context范圍 */} {/* value 必填 context傳遞的值 */} <ThemeContext.Provider value={{ ...nowTheme, handler: this.changeTheme.bind(this) }} > <div className="Admin"> <div className="LeftMenu"> <LeftMenu></LeftMenu> </div> <div className="RightContent"> <div className="RightContent-top"> <TopHeader></TopHeader> </div> <div className="RightContent-bottom"> <Dashborder></Dashborder> </div> </div> </div> </ThemeContext.Provider> </> ); //在訂閱組件中直接使用 //修改主題的方法 change(themeType) { console.log(themeType); //獲取provider傳遞方法 let { handler } = this.context; handler(themeType); } render() { let { themeButton } = this.state; return ( <> <div> <span>主題色:</span> <div> {/* 控制左側(cè)菜單和上header背景色 */} {themeButton.map((item, index) => { return ( <button key={index} onClick={this.change.bind(this, item.type)}> {item.name} </button> ); })} </div> </div> </> );
{/* 顏色選擇器 */} 背景色: <input type="color" name="selectbgColor" value={selectbgColor} onChange={this.changeColor.bind(this)} /> 字體色: <input type="color" name="selectColor" value={selectColor} onChange={this.changeColor.bind(this)} /> <button onClick={this.yesHandler.bind(this)}>確認(rèn)</button> //代碼區(qū)域操作事件向父級(jí)傳遞參數(shù) //確認(rèn)修改 yesHandler() { let { myhandler } = this.context; let { selectbgColor, selectColor } = this.state; console.log(selectbgColor, selectColor); myhandler(selectbgColor, selectColor); }
{/*監(jiān)聽(tīng)context value值*/} <ThemeContext.Consumer> {(value) => { let { backgroundColor, color } = value; return ( <> <span>背景色:{backgroundColor}</span> <span>文字色:{color}</span> </> ); }} </ThemeContext.Consumer>
組件生命周期解釋?zhuān)航M件初始化到銷(xiāo)毀整個(gè)過(guò)程。
生命周期三類(lèi):
Mounting(掛載):已插入真實(shí) DOM
Updating(更新):正在被重新渲染
Unmounting(卸載):已移出真實(shí) DOM
第一個(gè)階段: 代碼演示第一個(gè)階段初始化掛載階段 import React, { Component } from "react"; class App extends Component { constructor(props) { super(props); this.state = {}; console.log("初始化"); } componentDidMount() { console.log("掛載完成"); } render() { console.log("渲染"); return ( <> <div>測(cè)試</div> </> ); } } export default App;
添加了掛載之前周期
UNSAFE_componentWillMount() { console.log("掛載之前"); } //18.x 版本中UNSAFE_ 前綴
第二個(gè)階段:更新階段 能觸發(fā)類(lèi)組件更新 props state
添加了更新之前周期
componentWillUpdate() { console.log("更新之前"); }
第三階段卸載:
//卸載周期 componentWillUnmount() { console.log("組件卸載"); }
常用周期:
測(cè)試完成之后:18版本直接使用周期以上三個(gè)。
react推薦網(wǎng)絡(luò)請(qǐng)求在componentDidMount 卸載清除副作用 componentWillUnmount
確認(rèn)當(dāng)前組件是否更新周期
//確認(rèn)是否更新周期 //必須帶返回值 true false //提升性能 shouldComponentUpdate(nextProps, nextState, nextContext) { console.log(nextProps); if (nextProps.name == this.props.name) return false; else return true; } 不寫(xiě)該周期默認(rèn)是執(zhí)行更新
1.componentWillMount() - 在染之前執(zhí)行,在客戶(hù)端和服務(wù)器端都會(huì)執(zhí)行. 2.componentDidMount() - 是掛在完成之后執(zhí)行一次 3.componentWillReceiveProps() - 當(dāng)從父類(lèi)接收到 props 并且在調(diào)用另一個(gè)渲染器器之前調(diào)用。4.shouldComponentUpdatel) -根據(jù)特定條件返回 true 或 false如果你希望更新組件,請(qǐng)返回true 否則返它返回 false。 5.componentWillUpdate() - 是當(dāng)前組件state和props發(fā)生變化之前執(zhí)行 6.componentDidUpdate()-是當(dāng)前組件state和props發(fā)生變化執(zhí)行 7.componentWillUnmount0) - 從 DOM 卸載組件后調(diào)用。用于清理內(nèi)存空間
到此,相信大家對(duì)“react中context傳值和生命周期源碼分析”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。