React複習進階 - 高階組件的使用/配置裝飾品模式/新版context的使用

所謂高階組件即便是接受一個組件做爲參數, 返回一個新組件的函數, 用於提升組件的"自身能力", 提升組件複用性

1.普通高階組件

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
}

2.高階組件裝飾器寫法

首先須要幾個包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;

3.新版context的使用

寫一個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

相關文章
相關標籤/搜索