React 中高階函數與高階組件(上)

2021-02-21 itclanCoder
前言

React 中最大的一亮點,就是組件化開發模式,而編寫 React 組件,對於無狀態的組件,我們可以用函數式組件編寫,而複雜的組件(聰明組件/外層組件)可以用類class編寫組件

在 React 中提到了高階函數與高階組件,一直以來,對它們都是持以仰望的,逼格高的詞調,常常把自己給整暈的,做個記錄總結一下的



函數可以被作為參數傳遞

如下:經常用到的setTimeout,setInterval

setTimeout(function() {
  console.log('itclanCoder');
}, 2000);

setTimeout 是一個定時器函數,接收兩個參數,第一個參數是一個匿名函數,第二個參數是時間過了 2 秒後,執行匿名函數中的代碼

setInterval高階函數

setInterval(() => {
  console.log('http://coder.itclan.cn');
}, 2000);

setTinterval 是一個定時器函數,同樣接收兩個參數,第一個參數是箭頭函數,每個參數時間參數每隔 2 秒執行一次箭頭函數

說明

類似這樣的高階函數:clearInterval 清除定時器等,將函數作為形參數放到一個函數中執行的,這個函數可以視為高階函數數組中的一些迭代器函數都可以視為高階函數:map,filter,forEach,reduce,find等

函數作為返回值輸出

一個函數可以有返回值,也可以無返回值,若無指定返回值,它會默認返回undefined

函數是對象,這意味著函數可以存儲在一個變量,數組,或對象中,同時函數可以傳遞給函數,並由函數返回,它可以擁有屬性,也可以是一個值,可以像JavaScript中的其他表達式那樣被當做參數一個傳遞

function foo(x) {
  return function() {
    return x;
  };
}

上面的 foo 函數接收的形參是x,函數 foo 的返回值是一個匿名函數,匿名函數返回值返回形參x

那麼此時foo函數就是以函數作為返回值作為輸出的高階函數



定時器 setTimeout 應用
setTimeout(function() {
  console.log('itclanCoder');
}, 2000);

隔 2 秒後列印 itclancoder

定時器 setInterval 應用

setInterval(function() {
  console.log('http://coder.itclan.cn/');
}, 2000);

每隔 2 秒列印一次http://coder.itclan.cn/

Ajax應用

$.get('url?params',function() {
  console.log("獲取數據");
})

axios.get('url', function() {
    console.log("獲取數據");
})

上面的get函數都可以視為高階函數

Es5,Es5新增的一個迭代器方法

some(),every(),map(),forEach(),reduce(),find(),filter()等

函數節流應用

function throttle2(method, duration) {
  // 當前時間間隔內是否有方法執行,設置一個開關標識
  var runFlag = false;
  // 返回一個事件處理函數
  return function(e) {
    // 判斷當前是否有方法執行,有則什麼都不做,若為true,則跳出
    if (runFlag) {
      return false;
    }
    // 開始執行
    runFlag = true;
    // 添加定時器,在到達時間間隔時重置鎖的狀態
    setTimeout(function() {
      method(e);
      // 執行完畢後,聲明當前沒有正在執行的方法,方便下一個時間調用
      runFlag = false;
    }, duration);
  };
}

函數節流保證一段時間內只執行一次核心代碼,連續每隔一定的時間觸發執行的函數上面使用的是重置一個開關變量+定時器的方式實現函數節流

函數防抖應用

function debounce(method, duration) {
  var timer = null;
  return function() {
    var that = this,
      args = arguments;
    // 在本次調用之間的一個間隔時間內若有方法在執行,則終止該方法的執行
    if (timer) {
      clearTimeout(timer);
    }
    // 開始執行本次調用
    timer = setTimeout(function() {
      method.apply(that, args);
    }, duration);
  };
}

函數的防抖:延遲事件處理函數的執行,一定時間間隔內只執行最後一次操作

函數柯裡化

// 普通的add函數
function add(x, y) {
  return x + y;
}

// 柯裡化後
function curryingAdd(x) {
  return function(y) {
    return x + y;
  };
}

add(1, 2); // 3
curryingAdd(1)(2); // 3

以上是把add函數的x,y兩個參數變成了先用一個函數接收x然後返回一個函數去處理y參數

只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數。


概念: 高階組件就是接收一個組件作為參數並返回一個新組件的函數

說明: 高階組件是一個函數,並不是組件

例如:如下面的彈出框

<template>
   <div class="highfun-component-pop">
        <div class="highfun-component-pop-box">
             <div class="header">
                  <div>提示</div>
                  <div><i class="el-icon-circle-close icon-close-btn"></i></div>
             </div>
             <div class="content">
                     <div class="list">A</div>
                     <div class="list">B</div>
                     <div class="list">C</div>
                     <div class="list">D</div>
                     <div class="list">E</div>
             </div>
        </div>
        <div class="highfun-component-pop-box">
              <div class="header">
                  <div>提示</div>
                  <div><i class="el-icon-circle-close icon-close-btn"></i></div>
             </div>
             <div class="content2">
                    <div class="list2">A</div>
                    <div class="list2">B</div>
                    <div class="list2">C</div>
                    <div class="list2">D</div>
             </div>
        </div>
   </div>
</template>
<script>
export default {
  data() {
    return {

    }

},

}
</script>

<style>
.highfun-component-pop {
  display: flex;
  justify-content: center;
}

.highfun-component-pop .highfun-component-pop-box {
  width: 300px;
  height: 400px;
  border:1px solid #de3636;
  border-top: none;
}

.highfun-component-pop .highfun-component-pop-box:nth-child(1) {
  margin-right: 30px;
}

.highfun-component-pop .highfun-component-pop-box .header {
  display: flex;
  height: 50px;
  padding: 0 10px;
  justify-content: space-between;
  align-items: center;
  background:#de3636;
  color:#fff;
}

.highfun-component-pop .highfun-component-pop-box .header .icon-close-btn {
  font-size: 25px;
  color:#fff;
}
.highfun-component-pop .highfun-component-pop-box .content {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  align-content: center;
}

.highfun-component-pop .highfun-component-pop-box .content2 {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.highfun-component-pop .highfun-component-pop-box .list2{
  width: 100px;
  height: 100px;
  border:1px solid #de3636;
  margin: 10px;
  text-align: center;
  line-height: 100px;
}

.highfun-component-pop .highfun-component-pop-box .list {
  width: 80%;
  height: 40px;
  border: 1px solid #de3636;
  margin: 10px 0;
  text-align:center;
  line-height: 40px;
}
</style>

經過 UI,可以將上面的公共的部分以及不同的部分給提取出來,封裝成三個組件,分別為組件 A(公共部分),組件 B,組件 C

<template>
    <div class="highcompnent-demo-wrap">
        <div class="component-a">
            <div class="component-header">
                  <div>提示</div>
                  <div><i class="el-icon-circle-close icon-close-btn"></i></div>
             </div>
        </div>
        <div class="component-b">
            <div class="list">A</div>
            <div class="list">B</div>
            <div class="list">C</div>
            <div class="list">D</div>
            <div class="list">E</div>
        </div>
        <div class="component-c">
              <div class="component-list">A</div>
              <div class="component-list">B</div>
              <div class="component-list">C</div>
              <div class="component-list">D</div>
        </div>
    </div>
</template>

<style>
.highcompnent-demo-wrap {
     display: flex;
     justify-content: center;

}

.highcompnent-demo-wrap .component-a {
width: 300px;
height: 400px;
border:1px solid #de3636;
border-top: none;
}

.highcompnent-demo-wrap .component-b {
  width: 300px;
  height: 400px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.highcompnent-demo-wrap .component-b .list {
  width: 80%;
  height: 40px;
  border: 1px solid #de3636;
  margin: 10px 0;
  text-align:center;
  line-height: 40px;
}

.highcompnent-demo-wrap .component-c {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  width: 226px;
  height: 400px;
}

.highcompnent-demo-wrap .component-c .component-list {
  width: 100px;
  height: 100px;
  border:1px solid #de3636;
  text-align: center;
  line-height: 100px;
  margin-right: 10px;
  margin-bottom:10px;
}

.highcompnent-demo-wrap .component-header {
display: flex;
height: 50px;
padding: 0 10px;
justify-content: space-between;
align-items: center;
background:#de3636;
color:#fff;
}
</style>
<template>
    <div class="footer-component">
         <div>組件A</div>
         <div>組件B</div>
         <div>組件C</div>
    </div>
</template>
<style>
.footer-component {
  padding: 15px 0 0 0;
  width: 100%;
  display: flex;
  justify-content: space-around;
  
}

</style>

可以用create-react-app腳手架工具創建一個項目,在src目錄下創建一個components文件夾,這個文件主要用於存放我們的自定義組件

在components中創建一個highcomponent,同時在該文件夾內創建ComponentA.js,ComponentB.js,ComponentC.js

組件 A 公共組件

import React, { Component } from 'react';
import './componentA.css';

// 聲明一個函數A組件,返回結果是一個類組件,並接收一個參數WrappendComponent
function A(WrappendComponent) {
  return class ComponentA extends Component {
    render() {
      return (
        <div>
          <div className="highfun-component-pop-box">
            <div className="header">
              <div>提示</div>
              <div>X</div> // 這裡為了簡便,我直接用一個x替代了的
            </div>
            <div className="content">
              <WrappendComponent /> // 這裡是要渲染不同的內容
            </div>
          </div>
        </div>
      );
    }
  };
}

export default A; // 導出A函數組件

componentA.css

.pop-box {
  width: 300px;
  height: 400px;
  border: 1px solid #de3636;
  border-top: none;
}

.header {
  display: flex;
  height: 50px;
  padding: 0 10px;
  justify-content: space-between;
  align-items: center;
  background: #de3636;
  color: #fff;
}

.content {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  align-content: center;
}

組件 B

import React, { Component } from 'react';
import './componentB.css';
import A from './componentA'; // 引入A函數

// 類聲明B組件
class ComponentB extends Component {
  render() {
    return (
      <div>
        <div className="component-b">
          <div className="list">A</div>
          <div className="list">B</div>
          <div className="list">C</div>
          <div className="list">D</div>
        </div>
      </div>
    );
  }
}

export default A(ComponentB); // 導出調用A函數,同時將B組件讓A組件作為參數調用

componentB.css

.component-b {
  width: 300px;
  height: 400px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.component-b .list {
  width: 80%;
  height: 40px;
  border: 1px solid #de3636;
  margin: 10px 0;
  text-align: center;
  line-height: 40px;
}

組件 C

import React, { Component } from 'react';
import './componentC.css';
import A from './componentA';

class ComponentC extends Component {
  render() {
    return (
      <div>
        <div className="component-c">
          <div className="component-list">A</div>
          <div className="component-list">B</div>
          <div className="component-list">C</div>
          <div className="component-list">D</div>
        </div>
      </div>
    );
  }
}

export default A(ComponentC);

componentC.css

.component-c {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  width: 226px;
  height: 400px;
}

.component-c .component-list {
  width: 100px;
  height: 100px;
  border: 1px solid #de3636;
  text-align: center;
  line-height: 100px;
  margin-right: 10px;
  margin-bottom: 10px;
}

App.js 中

import React, { Component } from 'react';

import ComponentB from './components/highfun-component-popcomponent/componentB';
import ComponentC from './components/highfun-component-popcomponent/componentC';

import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="App">
        <ComponentB />
        <ComponentC />
      </div>
    );
  }
}

export default App;

App.css

.App {
  text-align: center;
  display: flex;
  justify-content: space-around;
}

說明

從上面的示例代碼中就可以看出 A 就是一個高階組件

⒈ 首先高階組件它是一個函數,並且函數返回一個類組件

⒉ 高階組件它需要接受一個形參數,作為在想要渲染地方以組件的形式插入

經過上面的代碼編寫:達到了組件復用的目的



多個組件都需要某個相同的功能,使用高階組件減少重複實現

react-redux 中的connect連接器就是一個高階組件

export default connect(mapStateToProps, mapDispatchToProps)(Header);


⒈ 如何編寫高階組件

⒉ 如何使用高階組件

⒊ 如在高階組件中實現傳遞參數

如何編寫高階組件

⒈ 實現一個普通組件

⒉ 將一個普通組件使用函數包裹

第 1 步實現一個普通組件

import React, { Component } from 'react';
// 用class類聲明一個componentD組件繼承自Component
export default class componentD extends Component {
  render() {
    return <div></div>;
  }
}

第 2 步-將普通組件使用函數包裹

import React, { Component } from 'react';
// 聲明一個函數組件ComponentD,同時接收一個形參WrappedComponent
function ComponentD(WrappedComponent) {
  return class componentD extends Component {
    render() {
      return (
        <div>
          <WrappedComponent />
        </div>
      );
    }
  };
}

export default ComponentD;

說明

編寫一個高階組件,首先要明確高階組件是一個函數

⒈ 先編寫一個普通的類組件

⒉ 聲明一個函數,接收一個形參,該函數返回一個類組件

⒊ 最後將該函數給導出

如何使用高階組件

⒈ higherOrderComponent(WrappedComponent)

⒉ @highOrderComponent

假設現在我編寫了一個組件compnentF.js組件,將該組件當做參數傳遞給組件 componentD,然後渲染到頁面上

以下為第一種使用方式,函數調用方式

組件 F-componentF

import React, { Component } from 'react';
import componentD from './componentD'; // 引入函數componentD高階組件

class componentF extends Component {
  render() {
    return <div>我是組件F</div>;
  }
}

export default componentD(componentF); // 將類組件componentF作為參數被組件componentD調用並導出

使用高階組件,還有另外一種方式,就是使用裝飾器方式,即@+函數名,它是一個語法糖,簡化了我們的寫法

方式 1-安裝 babel 插件在 babelrc 中配置

在使用這種裝飾器方式時,需要對create-react-app做一些配置,它默認是不支持裝飾器模式的,你需要對項目做一些配置

在create-react-app根目錄中終端下使用npm run eject,這條命令主要是將我們的配置項做一個反向輸出,暴露出隱藏的 webpack 配置項,這樣可以項目進行修改了的,注意它是不可逆的

使用裝飾器模式時:需要安裝兩個依賴:

cnpm install -D babel-preset-stage-2
cnpm install -D babel-preset-react-native-stage-0

然後你需要在根目錄下創建一個.babelrc文件,對.babelrc文件做一些配置

{
  "presets": ["react-native-stage-0/decorator-support"]
}

經過這麼配置後,就可以使用裝飾器了的

import React, { Component } from 'react';
import componentD from './componentD'; // 引入函數componentD高階組件

@componentD // 直接用@符號+高階組件componentD就可以了的
class componentF extends Component {
  render() {
    return <div>我是組件F</div>;
  }
}

export default componentF;

方式 2-經過 eject 後在 package.json 中的 plugins 中配置

當用eject將webpack一些配置彈射出來以後,會看到根目錄下的package.json文件下新增了很多文件

在babel對象處進行插件的配置,將@babel/plugin-proposal-decorators添加到plugins後

{
  "babel": {
    "presets": [
      "react-app"
    ],

    "plugins": [
        [
            "@babel/plugin-proposal-decorators",
            { "legacy": true }
        ]
    ]

  }
}

出現警告提示

當使用裝飾器模式時,在 vscode 中會有一警告的提示

解決 vscode 警告問題

在vscode中的設置中tsconfig啟動Experimental Decorators就可以解決此警告

經過這麼配置後就可以使用裝飾模式模式了的-即@+函數名簡寫的方式

非裝飾器普通模式寫法 

import React, { Component } from 'react';
import './componentB.css';
import A from './componentA';

class ComponentB extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <div className="component-b">
          <div className="list">A</div>
          <div className="list">B</div>
          <div className="list">C</div>
          <div className="list">D</div>
        </div>
      </div>
    );
  }
}

export default A(ComponentB); // 需要調用高階組件

裝飾器寫法

import React, { Component } from 'react';
import './componentB.css';
import A from './componentA';

@A
class ComponentB extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <div className="component-b">
          <div className="list">A</div>
          <div className="list">B</div>
          <div className="list">C</div>
          <div className="list">D</div>
        </div>
      </div>
    );
  }
}

export default ComponentB; // 直接導出組件即可

說明

在同一個組件中可以組合使用高階函數,能夠無限的嵌套下去,如果不用裝飾器函數,你會發現代碼將變得非常難以理解,也不好維護

import React, { Component } from 'react';
import A from './componentA';
import componentD from './componentD';

@A
@comonentD
class componentF extends Component {
  render() {
    return <div>我是組件F</div>;
  }
}

export default componentF;

為什麼需要 eject 暴露呢

因為默認create-react-app雖然已經內已經安裝了 @babel/plugin-proposal-decorators插件,但是需要自己進行配置

若不進行配置,它是不支持裝飾器模式的

結語

本小節主要介紹了React中的高階函數以及高階組件,高階函數具體有哪些應用以及什麼是高階組件,如何編寫高階組件

如果您有問題,歡迎評論下方留言,一起學習探討


記帳就用輕記帳


公眾號(ID:itclanCoder)

碼能讓您早脫菜籍,文能讓您洗淨鉛華

  可能您還想看更多:


文章都看完了不點個在看嗎


相關焦點

  • React組件邏輯復用的那些事兒
    Mixins 的原理Mixins 的原理可以簡單理解為將一個 mixin 對象上的方法增加到組件上。類似於 $.extend 方法,不過 React 還進行了一些其它的處理,例如:除了生命周期函數外,不同的 mixins 中是不允許有相同的屬性的,並且也不能和組件中的屬性和方法同名,否則會拋出異常。
  • 《深入淺出React和Redux》(3) - Export & Import, 高階組件
    開發輔助工具React Devtools可以檢視react組件的樹形結構,以及每個節點上的內容,安裝chrome插件即可使用。高階組件高階組件(Higher Order Component,HOC)是使用react的一種模式,用於增強現有組件的功能。簡單來說,一個高階組件就是一個函數,這個函數接受一個組件作為輸入,然後返回一個新的組件作為結果,而且,返回的新組件擁有了輸入組件所不具有的功能。
  • 為什麼要在函數組件中使用React.memo?
    ❞給憨憨帶上腦子 - 使用memo進行包裹給函數組件帶上腦子當我們給一個函數組件帶上腦子的時候,就想下面這樣import React form 'react';const FuncComponent = ()=>{ return <h1&
  • 30 分鐘精通 React 新特性——React Hooks
    Hooks本質上就是一類特殊的函數,它們可以為你的函數型組件(function component)注入一些特殊的功能。咦?這聽起來有點像被詬病的Mixins啊?難道是Mixins要在react中死灰復燃了嗎?當然不會了,等會我們再來談兩者的區別。總而言之,這些hooks的目標就是讓你不再寫class,讓function一統江湖。React為什麼要搞一個Hooks?
  • ReactNative 的組件架構設計
    todo 一個問題:由於 react 是面向狀態編程,相當於 react 的組件只關注數據的最終狀態,數據是怎麼產生的並不關心,但是某些場景下,數據如何產生的是會影響到組件的一些行為的【比如一個新增行要求有動畫效果,查詢出的行就不需要等】,這在 RN 中很難描述。。。。。
  • React源碼分析與實現(一):組件的初始化與渲染
    react最初的設計靈感來源於遊戲渲染的機制:當數據變化時,界面僅僅更新變化的部分而形成新的一幀渲染。所以設計react的核心就是認為UI只是把數據通過映射關係變換成另一種形式的數據,也就是展示方式。傳統上,web架構使用模板或者HTML指令構造頁面。
  • React Hook 入門教程
    react hook 產生的原因在組件之間復用狀態邏輯很難組件之間復用狀態邏輯很困難,我們可能會把組件連結到我們的 store 裡面。當然我們用 render props 或者是 高階組件 來解決,但是他們都是需要你改變你目前寫組件的邏輯。或者說改變組件的機構,並且當你看DOM 結構和 React devtool 的時候,你會發現你的組件進入了「嵌套地獄」。各種 provider、consumers、高階組件、render props ,多層嵌套,難以調試。
  • React Hooks 原理與最佳實踐
    從名字上就可以看出來,高階組件肯定和高階函數有什麼千絲萬縷的關係。高階組件的本質是一個高階函數,它接收一個組件,返回一個新的組件。在這個新的組件中的狀態共享,通過 props 傳給原來的組件。以剛剛那個 Toggle 組件為例子,高階組件同樣可以被多次復用,常常可以配合裝飾器一起使用。
  • 30 分鐘精通 React 今年最勁爆的新特性 —— React Hooks
    Hooks本質上就是一類特殊的函數,它們可以為你的函數型組件(function component)注入一些特殊的功能。咦?這聽起來有點像被詬病的Mixins啊?難道是Mixins要在react中死灰復燃了嗎?當然不會了,等會我們再來談兩者的區別。總而言之,這些hooks的目標就是讓你不再寫class,讓function一統江湖。React為什麼要搞一個Hooks?
  • React系列六 - 父子組件通信
    子組件是class組件我們這裡先演示子組件是class組件:import React, { Component } from 'react';// 1.類子組件class ChildCpn1 extends Component {  constructor(
  • React組件測試虛擬DOM的方法
    淺渲染將組件渲染成虛擬DOM對象,但與通常的渲染過程不同的是,它只渲染第一層,而不涉及所有子組件,因此處理速度很快。淺渲染不需要真實瀏覽器DOM環境,也無法實現與DOM互動。淺渲染使用react-addons-test-utils模塊的createRenderer()函數創建一個渲染器,渲染器渲染組件並緩存渲染出的虛擬DOM節點,通過調用渲染器的getRenderOutput()函數獲得虛擬DOM對象。
  • 函數式編程看React Hooks(一)簡單React Hooks實現
    在面向對象程序編程裡,電腦程式會被設計成彼此相關的對象函數式強調在邏輯處理中不變性。面向對象通過消息傳遞改變每個Object的內部狀態。兩者是截然不同的編程思想,都具有自己的優勢,也因為如此,才使得我們從 class組件 轉化到 函數組件式,有一些費解。從 react 的變化可以看出,react 走的道路越來越接近於函數式編程,輸入輸出一致性。
  • React 16.8 之 React Hook
    React Hook 為何而存在1.在組件之間復用狀態邏輯很難雖然我們可以用render props 和高階組件來解決這一問題,但是這不僅會容易形成「嵌套地獄」,還會面臨一個很尷尬的問題,那就是複雜邏輯難寫
  • React知識點總結
    所有的事件,都被掛載到 document 上 // 4.// fixed 元素要放在 body 上,有更好的瀏覽器兼容性。:import React from 'react'// 創建 Context 填入默認值(任何一個 js 變量)const ThemeContext = React.createContext('light')// 底層組件 - 函數是組件function ThemeLink (props) { // const theme
  • 精通react/vue組件設計之實現一個輕量級可擴展的模態框組件
    基於react實現一個Modal組件2.1.雖然這樣已經基本實現了鍵盤關閉的功能,但是這樣的代碼明顯不夠優雅,所以我們來完善以下,我們可以將鍵盤關閉的方法抽離出來,然後在useEffect的第一個回調函數中返回另一個函數(該函數裡是組件卸載前的鉤子),當組件卸載時我們將事件監聽移除,這樣可以提高一些性能,對內存優化也有幫助:const closeModal = function (event) {
  • 在 React 組件中使用 Refs 指南
    在 React 中使用 Refs您可以通過多種方式使用 refs :接下來,讓我們看看每一種實現方式:React.createRef()可以使用該 React.createRef() 函數創建 Refs ,並通過該 ref 屬性附加到 React 組件中的 HTML 元素。通常在組件的構造函數內創建 ref ,使其在整個組件中可用。
  • React Hooks 與Vue3.0 Function based API的對比?
    引用官網的一段話:從概念上講,React 組件更像是函數。而 Hooks 則擁抱了函數,同時也沒有犧牲 React 的精神原則。Hooks 提供了問題的解決方案,無需學習複雜的函數式或響應式編程技術。另外,Hooks 是100%向後兼容的,也是完全可選的。
  • react複雜組件 - CSDN
    react 組件引用組件I've been experimenting a lot with both React and Cloudinary over the past six months and it's been a blast -- I'm learning a ton while also recovering the ambition and thirst
  • React Hooks使用小結
    在hooks出生之前,react沒有將可復用性行為添加到組件到能力,針對這個問題廣大開發者開始使用renderProps 或者 高階組件來實現此目的。但是,說實話這些方法還是比較麻煩的,需要重新組織項目或者組件的組織結構。
  • 【重學React】動手實現一個react-redux
    我們知道,react 中高階組件可以實現邏輯的復用。文中所用到的 Counter 代碼在 https://github.com/YvetteLau/Blog 中的 myreact-redux/counter 中,建議先 clone 代碼,當然啦,如果覺得本文不錯的話,給個star鼓勵。