天天看點

react——@修飾器——高階元件的使用——通過裝飾器來調用高階元件——簡單修改樣式

使用裝飾器@

裝飾器 用來裝飾類的,可以增強類,在不修改類的内部的源碼的同時,增強它的能力(屬性或方法)

裝飾器使用​​

​@函數名​

​​寫法,對​

​類​

​​進行裝飾,目前在js中還是提案,使用需要配置相關相容代碼庫。

react腳手架建立的項目預設是不支援裝飾器,需要手動安裝相關子產品和添加配置檔案

💥安裝相關子產品

yarn add -D customize-cra react-app-rewired  @babel/plugin-proposal-decorators      

💥修改package.json檔案中scripts指令

"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  }      

💥在項目根目錄中添加​

​config-overrides.js​

​​配置檔案

此檔案可以了解為就是​​

​webpack.config.js​

​的擴充檔案

const { resolve } = require('path')
const { addDecoratorsLegacy, override } = require('customize-cra')

// 增強自定義給webpack添加相關配置
const custom = () => config => {
  config.resolve.alias['@'] = resolve('./src')
  return config
}

module.exports = override(addDecoratorsLegacy(), custom())      

一般加上這個就行:

// 增量配置目前項目中的webpack配置,建議在react18中不要用
// 建議在react18中也不要用裝飾器
// override 方法,如果webpack中有此配置則,覆寫,如果沒有則添加
const { addDecoratorsLegacy, override } = require('customize-cra')

// 追加上一個裝飾器
module.exports = override(addDecoratorsLegacy())      

裝飾器的使用

裝飾類

裝飾函數,在裝飾時它沒有寫小括号,target它就是目前你裝飾的類

添加靜态方法/屬性:

不是成員方法

const handle = target =>{
    target.run = ()=>{
        console.log("run");
    }
}

@handle
class Demo {};
const d = new Demo();
Demo.run();      

添加成員方法/屬性:

const handle = target =>{
    target.prototype.run = ()=>{
        console.log("run");
    }
}

@handle
class Demo {};
const d = new Demo();
d.run();      

裝飾器加上了小括号,則定義函數時一定要傳回一個新函數

const handle = (msg) => target =>{
    target.prototype.run = ()=>{
        console.log("run",msg);
    }
}

@handle("我愛你")
class Demo {};
const d = new Demo();
d.run();      

裝飾成員屬性

裝飾器裝飾成員屬性,裝飾時沒有寫小括号

裝飾器裝飾成員屬性,裝飾時沒有寫小括号
target 裝飾的類的執行個體 new Demo  this
key 目前的成員屬性名稱  username
description 就是目前屬性在對象中它的描述 Object.defineProperty

const handle = (target, key,) => {
  // 設定目前屬性為隻讀屬性
  // description.writable = false
  console.log(target, key, description)
}

class Demo {
  @handle
  username = 'abc'
}      

高階元件

定義高階元件,用來進行全局布局

1.它就是一個函數

2.參數首字母大寫,因為你傳入的是一個元件,在react中元件的調用必須首字母大寫

3.傳回一個元件

高階元件的使用場景

1, 需要代碼重用時, react如果有多個元件都用到了同一段邏輯, 這時,就可以把共同的邏輯部分提取出來,

利用高階元件的形式将這段邏輯整合到每一個元件中, 進而減少代碼的邏輯重複。

2, 需要元件增強優化時, 比如我們在項目中使用的元件有些不是自己寫的, 而是從網上C下來的,

但是第三方寫的元件可能比較複雜, 有時不能完全滿足需求, 但第三方元件不易修改, 此時也可以用高階元件,

在不修改原始元件的前提下, 對元件添加滿足實際開發需求的功能。

高階元件的實作方式

高階元件的實作方式有兩種:

1, 屬性代理: 通過建立新組建來包裹原始元件, 把原始元件作為新組建的子元件渲染

功能: 可實作對原始元件的 props資料更新 和 元件模闆更新。

下面是實作屬性代理的代碼片段:

(1), 建立高階元件檔案 MyHOC.jsx

function MyHoc(OldCom){
      return class NewCom extends React.Component{
        render(){
            let newProps = { age: 10, sex: '男' }
            return (
              <OldCom {...newProps} ></OldCom>
            )
        }
      }
    }

// 導出高階元件函數
export default MyHOC;

// 屬性代理: 通過建立新組建來包裹原始元件, 把原始元件作為新組建的子元件渲染
// 功能: 可實作對原始元件的 props資料更新 和 元件模闆更      

(2), 在檔案中建立函數 函數的參數是一個元件OldCom(參數可以自定義), 函數的傳回值也是一個元件 NewCom(自定義)

反向繼承: 通過建立新組建繼承自原始元件, 把原始元件作為父元件

功能: 可實作對原始元件的state狀态資料更新 和 元件模闆更新。

下面是實作反向繼承的代碼片段:

function MyHOC (OldCom){
      return class NewCom extends OldCom{
        componentDidMount() {
          this.setState({ name: '李四' })
        }
        render() {
          return super.render()
        }
      }
    }

// 導出高階元件函數
export default MyHOC;

 // 反向繼承的state資料, 不能在render中改, 會進入死循環
 // 一般在生命周期函數或自定義函數中更新state      

簡單的樣式修改

一、沒有使用cssModule時,隻能直接導入

import './style.css'
<div className="todo-title">任務清單</div>      

注意手動添加辨別符

例如:

.todo-title {
  color: red;
}      

二、 在react中create-react-app工程,它内置了cssModule功能,但是檔案字尾一定要有​

​xxx.module.css/scss​

​​ 如果有scss檔案,必須得安裝​

​yarn add sass​

import styles from './style.module.css'      
<div className={styles.title}>任務清單</div>
<span className={done ? style.title : ''}>{title}</span>      

通過裝飾器來調用高階元件

完成修飾後類元件導出:

@withLayout
class Child extends Component{
  render() {
          return ()
  }
}
export default Child;
//export default withRouter(Child);      

繼續閱讀