react中的三種方式實現祖孫資料共享
最近在學習react的hook,看完useContext後總結一下react中的三種實現祖孫資料共享的方式。
這是一個主題換膚的例子,分別用下面三種方式來實現。先上效果圖:
下面是app.js中的程式碼:
import React from 'react';
import './App.css'
import PropsContext from './pages/props-context'
import ClassContext from './pages/class-context'
import UseContext from './pages/hook-context'
function App() {
return (
<div className="App">
{/* 使用props實現資料共享 */}
<PropsContext ></PropsContext >
<hr/>
{/* 使用class context實現資料共享 */}
<ClassContext></ClassContext>
<hr />
{/* 使用userContext hook實現資料共享 */}
<UseContext></UseContext>
</div>
);
}
export default App;
1. props-context
顧名思義使用props的方式將祖先元件的資料一層層傳遞給子元件。和vue一樣,父元件通過自定義屬性的方式將資料作為props傳給子元件,不同的是react中可以傳遞一個HTML結構(實質上是可以通過JSX轉換的js物件),render-props正是利用了這一點靈活渲染DOM實現自定義HTML結構。
import React, { Component } from 'react'
import './index.css'
const COLOR = ['#B5E61D', '#ED1C24', '#00A2E8', '#A349A4', '#B97A57', '#A349A4']
export default class grandfather extends Component {
state = {
theme: COLOR[0]
}
changeColor = () => {
this.setState({
theme: COLOR[Math.ceil(Math.random() * (COLOR.length - 1))] // 隨機獲取顏色
})
}
render() {
return (
<div className="grandfather">
<div>當前主題為:{this.state.theme}</div>
<div style={{ color: this.state.theme }}>grandfather</div>
<Father theme={this.state.theme}></Father>
<button className="fixed1" onClick={this.changeColor}>換膚</button>
</div>
)
}
}
function Father(props) {
return (
<div className="father">
<div style={{ color: props.theme }}>father</div>
<Son theme={props.theme}></Son>
</div>
)
}
function Son(props) {
return (
<div className="son">
<div style={{ color: props.theme }}>son</div>
</div>
)
}
2. class-context
在class類元件中使用context來將資料共享給子元件,不同於props-context,這種方式可以跨越N個父元件直接將資料傳給子元件,並不需要父->子、父->子。。。鏈式傳遞。VUE中也有使用context來實現祖孫資料共享的方案,只不過人家叫provide-inject,而react中叫provide-consumer。
import React, { Component, createContext } from 'react'
import './index.css'
const COLOR = ['#B5E61D', '#ED1C24', '#00A2E8', '#A349A4', '#B97A57', '#A349A4']
const Theme = createContext(COLOR[1])
export default class grandfather extends Component {
state = {
theme: COLOR[0]
}
changeColor = () => {
this.setState({
theme: COLOR[Math.ceil(Math.random() * (COLOR.length - 1))] // 隨機獲取顏色
})
}
render() {
return (
<div className="grandfather">
<div>當前主題為:{this.state.theme}</div>
<div style={{ color: this.state.theme }}>grandfather</div>
<Theme.Provider value={this.state.theme}>
<Father></Father>
</Theme.Provider >
<button className="fixed2" onClick={this.changeColor}>換膚</button>
</div>
)
}
}
function Father(props) {
return (
<div className="father">
<Theme.Consumer>
{
(theme) => {
return <div style={{ color: theme }}>father</div>
}
}
</Theme.Consumer>
<Son></Son>
</div>
)
}
function Son(props) {
return (
<div className="son">
<Theme.Consumer>
{
(theme) => {
return <div style={{ color: theme }}>son</div>
}
}
</Theme.Consumer>
</div>
)
}
3. hook-context
hook中提供了useContext這個鉤子配合createContext去實現爺孫資料共享。相當於是provide-useComtext模式。在hook中資料通過useState鉤子存放,實參為初識值,返回值為存放的資料以及相應的改變這個資料的函式。
import React, { useState ,useContext, createContext } from 'react'
import './index.css'
const COLOR = ['#B5E61D', '#ED1C24', '#00A2E8', '#A349A4', '#B97A57', '#A349A4']
const Theme = createContext('#B5E61D')
export default function Grandfather() {
const [ theme, setTheme ] = useState(COLOR[0])
function changeColor() {
setTheme(COLOR[Math.ceil(Math.random() * (COLOR.length - 1))])
}
return (
<div className="grandfather">
<div>當前主題為:{theme}</div>
<div style={{ color: theme }}>grandfather</div>
<Theme.Provider value={theme}>
<Father></Father>
</Theme.Provider>
<button className="fixed3" onClick={changeColor}>換膚</button>
</div>
)
}
function Father(props) {
return (
<div className="father">
// 在函式元件中一樣可以使用Context.Consumer語法來拿資料
<Theme.Consumer>
{
(theme) => <div style={{ color: theme }}>father</div>
}
</Theme.Consumer>
<Son></Son>
</div>
)
}
function Son(props) {
const theme = useContext(Theme) // 注意此處的Theme是開頭createContext('#B5E61D')的返回值Theme
return (
<div className="son">
<div style={{ color: theme }}>son</div>
</div>
)
}
相關文章
- Java中Singleton的三種實現方式解析Java
- Java中Elasticsearch 實現分頁方式(三種方式)JavaElasticsearch
- springAOP的三種實現方式Spring
- Javascript 中實現物件原型繼承的三種方式JavaScript物件原型繼承
- js實現繼承的三種方式JS繼承
- vue中實現路由跳轉的三種方式(精選)Vue路由
- 三種 Post 提交資料方式
- python 三種方式實現截圖Python
- tensorflow載入資料的三種方式
- React 程式碼共享最佳實踐方式React
- 單點登入的三種實現方式
- 實現圖片染色效果的三種方式
- Go定時器的三種實現方式Go定時器
- React | ref三種使用方式總結React
- PHP 三種方式實現鏈式操作PHP
- 前端實現文字跑馬燈的三種方式前端
- 三欄式佈局的幾種實現方式
- 實現圖片懶載入的三種方式
- 實現ABAP條件斷點的三種方式斷點
- Java實現多執行緒的三種方式Java執行緒
- 實現布隆過濾器的三種方式過濾器
- Flutter 頁面間資料傳遞(共享)的幾種常用方式Flutter
- selenium中的三種等待方式
- MongoDB中優雅刪除大量資料的三種方式純尹MongoDB
- [譯] React 實現條件渲染的多種方式和效能考量React
- React 提供了幾種方式來實現條件渲染React
- js保護內部資料的三種方式JS
- 前端請求後端資料的三種方式!前端後端
- 使用Vue實現圖片上傳的三種方式Vue
- 實現 ABAP 條件斷點的三種方式分享斷點
- Vuex如何實現資料共享Vue
- Golang中map的三種宣告方式和簡單實現增刪改查Golang
- React 中獲取資料的 3 種方法:哪種最好?React
- MyBatis中主鍵回填的兩種實現方式MyBatis
- 分散式鎖解決併發的三種實現方式分散式
- 獲得資料庫操作日誌的三種方式資料庫
- 前端中的同源策略與三種跨域資源共享方法前端跨域
- 三種方式實現觀察者模式 及 Spring中的事件程式設計模型模式Spring事件程式設計模型