對 React Context 的理解以及應用

2021-10-01 21:42:59 字數 3834 閱讀 1563

很多優秀的react元件都通過context來完成自己的功能:

在react元件開發中,如果用好context,可以讓你的元件變得強大,而且靈活。

簡單說就是,當你不想在元件樹中通過逐層傳遞props或者state的方式來傳遞資料時,可以使用context來實現跨層級的元件資料傳遞。

使用props或者state傳遞資料,資料自頂下流。

如何使用context

如果要context發揮作用,需要用到兩種元件,乙個是context生產者(provider),通常是乙個父節點,另外是乙個context的消費者(consumer),通常是乙個或者多個子節點。所以context的使用基於生產者消費者模式。

對於父元件,也就是context生產者,需要通過乙個靜態屬性childcontexttypes宣告提供給子元件的context物件的屬性,並實現乙個例項getchildcontext方法,返回乙個代表context的純物件 (plain object) 。

import react from 'react'

import proptypes from 'prop-types'

class parentcomponent extends react.component

// 宣告context物件屬性

static childcontexttypes =

// 返回context物件,方法名是約定好的

getchildcontext () =this.state;

console.log( 'from top msg', 'parent-state-parentval:',parentval )}}

}render ()

}

而對於context的消費者,通過如下方式訪問父元件提供的context。

import react from 'react'

import proptypes from 'prop-types'

class childcomponent extends react.component

render () = this.context

console.log(name)

fun()

}}

子元件需要通過乙個靜態屬性contexttypes宣告後,才能訪問父元件context物件的屬性,否則,即使屬性名沒寫錯,拿到的物件也是undefined。

請謹慎使用,因為這會使得元件的復用性變差。

使用context的通用的場景包括管理當前的locale,theme,或者一些快取資料,這比替代方案要簡單的多。

react.createcontext

const mycontext = react.createcontext(defaultvalue);
建立乙個context物件。當react渲染乙個訂閱了這個context物件的元件,這個元件會從元件樹中離自身最近的那個匹配的provider中讀取到當前的上下文值。

context.provider

每個context物件都會返回乙個provider react元件,它允許消費元件訂閱context的變化。

當提供者的value值發生變化時,它內部的所有消費元件都會重新渲染。

提供者及其內部消費者元件都不受制shouldcomponentupdate函式,因此當消費者元件在其祖先元件退出更新的情況下也能更新。

class.contexttype

class myclass extends react.component 

componentdidupdate()

componentwillunmount()

render()

}myclass.contexttype = mycontext;

掛載在類上的contexttype屬性會被重賦值為乙個由react.createcontext()建立的context物件。

這能讓你使用this.context來消費最近context上的那個值。你可以在任何生命週期中訪問到它,包括渲染函式中。

可以使用static這個類屬性來初始化你的contexttype。

class myclass extends react.component 

}

context.consumer

傳遞給函式的value值等同於往上元件樹離這個context最近的提供者提供的value值。如果沒有對應的provider,value引數等同於傳遞給createcontext()的defaultvalue。

注意:當 provider 的父元件進行重渲染時,可能會在 consumers 元件中觸發意外的渲染。

關鍵語句 ( 類似與 eventbus 裡的 bus.js 作為乙個媒介,該句用於方便理解 )

createcontext.js

import react from 'react';

export default react.createcontext('createcontext-test-defaultval');

提供初始 context 值的元件

parent.js

import react from 'react';

import createcontext from './createcontext'; // 引入媒介

render()

要獲取context值的元件

只要在 createcontext.provider 裡,不用管中間隔了多少層,只需要在使用context的元件內引入媒介即可

import react from 'react';

import createcontext from './createcontext'; // 引入媒介

class comtest extends react.component

render())}}

// comtest.contexttype = createcontext;

export default comtest;

為了確保 context 快速進行重渲染,react 需要使每乙個 consumers 元件的 context 在元件樹中成為乙個單獨的節點。

// theme context,預設的 theme 是 「light」 值

const themecontext = react.createcontext('light');

// 使用者登入 context

const usercontext = react.createcontext();

render() = this.props;

return (

);}}

function layout()

// 乙個元件可能會消費多個 context

function content()

)});

}

新版 react context的寫法

祖元件 import react,from react import cnode from components cnode type propstype type statetype 這裡要匯出這個上下文,下面的子孫元件哪個用到context的東西哪個就引入一下 export const info...

對SQLiteOpenHelper類的理解

使用sqliteopenhelper對資料庫進行版本管理 因為我們開發的軟體可能會安裝在成百上千個使用者的手機上,如果應用使用到了sqlite資料庫,我們必須在使用者初次使用軟體時建立出應用使用到的資料庫表結構及新增一些初始化記錄,另外在軟體公升級的時候,也需要對資料表結構進行更新。那麼,我們如何才...

對pthread cond wait 函式的理解

原文 了解 pthread cond wait 的作用非常重要 它是 posix 執行緒訊號傳送系統的核心,也是最難以理解的部分。首先,讓我們考慮以下情況 執行緒為檢視已鏈結列表而鎖定了互斥物件,然而該列表恰巧是空的。這一特定執行緒什麼也幹不了 其設計意圖是從列表中除去節點,但是現在卻沒有節點。因此...