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 }
首先須要幾個包git
yarn add react-app-rewired customize-cra @babel/plugin-proposal-decorators -D
跟目錄新建config-overrides.js (至關於vue.config.js) 內容以下github
const { override, addDecoratorsLegacy } = require('customize-cra'); module.exports = override( addDecoratorsLegacy(), );
修改HocDemo.jsbabel
//其餘部分不變 其中裝飾器必須使用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包裹過的組件都有消費者功能
實現跨層級組件通訊 父=>孫app
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
demo代碼 https://github.com/ShangZzz/h...ide