HOC函數將父級屬性鄉下傳遞,並追加新屬性,爲Dumb添加樣式和newNamevue
// App.js
import React from 'react';
import Dumb from './HocDemo';
function App() {
return (
<div className="App">
<Dumb name="木偶組件" color="#afa"/>
</div>
);
}
export default App;
// HocDemo.js
import React from 'react'
// 傳入一個組件返回一個函數式組件
const HOC = (Comp) => (props) => {
const style = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '500px',
height: '300px',
border: `2px solid ${props.color}`,
}
return <Comp style={style} {...props} newName="高階組件" />
}
// 木偶組件
function Dumb(props) {
return (
<div style={props.style}>
我是{props.newName || props.name} || 本體是{props.name}
</div>
)
}
export default HOC(Dumb);
複製代碼
一樣還能夠爲Dumb增長生命週期等,以便處理邏輯react
// 修改HOC函數 在函數內部定義一個組件 最後將組件返回
const HOC = (Comp) => {
class NewDumb extends React.Component {
componentDidMount() {
console.log('NewDumb')
}
render() {
const style = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '500px',
height: '300px',
border: `2px solid ${this.props.color}`,
}
return <Comp style={style} {...this.props} newName="高階組件" />
}
}
return NewDumb
}
複製代碼
首先須要幾個包bash
yarn add react-app-rewired customize-cra @babel/plugin-proposal-decorators -D
複製代碼
跟目錄新建config-overrides.js (至關於vue.config.js) 內容以下babel
const { override, addDecoratorsLegacy } = require('customize-cra');
module.exports = override(
addDecoratorsLegacy(),
);
複製代碼
修改HocDemo.jsapp
//其餘部分不變 其中裝飾器必須使用class聲明組件
@HOC
class Dumb extends React.Component{
render(){
const { style, newName, name } = this.props
return (
<div style={style}>
我是{newName || name} || 本體是{name}
</div>
)
}
}
export default Dumb;
複製代碼
寫一個Context.js 在App.js中使用, 聲明一個上下文和初始化數據store, 封裝兩個函數withConsumer、withProvider 經過裝飾器使父級組件具備提供者功能 則Container組件下 被withConsumer包裹過的組件都有消費者功能 實現跨層級組件通訊 父=>孫ide
import React, { Component } from "react";
// 生成一個上下文
const Context = React.createContext();
const store = {
name: "Zzz",
};
// 爲Provider封裝一個高階組件
const withProvider = Comp => props => (
<Context.Provider value={store}>
<Comp {...props} />
</Context.Provider>
);
// 爲Consumer封裝一個高階組件
const withConsumer = Comp => props => (
<Context.Consumer>
{value => <Comp {...props} value={value} />}
</Context.Consumer>
);
//使孫子組件足有消費能力
@withConsumer
class Grandson extends Component {
render() {
return <div>{this.props.value.name}</div>;
}
}
//是父組件具備提供能力
@withProvider
class Provider extends Component {
render() {
return <div><Container/></div>;
}
}
// 一個容器組件
function Container(props) {
return (
<div> <Container2/> <Container3/> </div>
)
}
// 一個容器組件2
function Container2(props) {
return (
<div> <Grandson/> </div>
)
}
// 一個容器組件3
function Container3(props) {
return (
<div> Container3 </div>
)
}
export default Provider
複製代碼