天天看點

超性感的React Hooks(一):為何她獨具魅力

超性感的React Hooks(一):為何她獨具魅力

正如标題所示,我準備寫一系列文章介紹React Hooks。

過去大半年裡,我将React Hooks應用到了許多大型項目,其中5個全新重構,其他項目由于時間關系少量使用。

這些項目包括

•React Native•基于ant-design-pro重構的中背景應用•基于React,專注于小程式開發的Taro應用•以create-react-app為基礎,自主建構的web應用•基于beidou架構的改造的同構應用等

截止目前為止,其中一個項目useState使用2053次。

超性感的React Hooks(一):為何她獨具魅力

在大量使用了React Hooks之後,我有很多東西想要跟大家分享,也算是對自己這一年的成長做一個總結。

網上有大量的文章能夠教會大家如何使用React hooks,但很少有文章能夠指引我們如何用好。而這,也是我這次總結的目的所在。

這系列文章将不僅僅隻是簡單的介紹React Hooks相關的api,也不會為了逼格而過于深入源碼,我會專注于實踐應用,恰到好處的把該說的東西說得通俗易懂。也算是自己對知識是否掌握牢固的一次有效檢驗。

文章會有很多篇,隻能利用空餘時間寫,可能要一個多月甚至更久才能寫完,希望感興趣的同學能有點耐心,文章會優先在我的公衆号不知非攻中釋出。本文就先總結一下為什麼React Hooks值得入手,并且萬萬不能錯過。

閱讀本系列文章,需要有相對紮實的JS基礎,并且對React有簡單的了解。如果你覺得自己還不具備這樣的條件,沒關系,關注我的公衆号,我之前寫的基礎進階系列文章必定能夠幫助大家夯實基礎。

這系列文章雖然主要是分析React hooks,但是也可以作為React的入門教程,我會盡量通俗易懂。

React Hooks是React的一次成功自我颠覆。

這是我大量使用React Hooks之後的真實感受。

React團隊随時都在想着如何颠覆自己。對于主攻React的童鞋來說,真的是幸福又痛苦。

而React Hooks給我的感覺,無疑是幸福大于痛苦的。

一、肉眼可見的簡潔

先用一張圖簡單對比一下:

超性感的React Hooks(一):為何她獨具魅力

左側的代碼,是學習React入門的經典demo。右側的代碼,則是使用新的方式實作同樣的功能。

當然,簡潔力度有限,還不夠震撼,說服力不夠強。再來一個例子。

基于上面的簡單計數元件,強行套一個受控元件的思維,下圖是實作對比圖。

超性感的React Hooks(一):為何她獨具魅力

代碼行數,整整少了幾乎一半。

import React, { useState, useEffect } from 'react';

interface Props {
  value: number,
  onChange: (num: number) => any
}

export default function Counter({ value, onChange }: Props) {
  const [count, setCount] = useState<number>(0);

  useEffect(() => {
    value && setCount(value);
  }, [value]);

  return [
    <div key="a">{count}</div>,
    <button key="b" onClick={() => onChange(count + 1)}>
      點選+1
    </button>
  ]
}           

複制

我想,所有人都知道,代碼少一半,意味着什麼!

二、上手更簡單

當一個團隊選擇了React作為主要的技術棧,面臨的一個大的問題,就是招人相對困難<至少成都是這樣>,這一點,我深有體會,10個投來的履歷,9個都是會vue的,還有一個會React的,都是騙人的,2年時間,我愣是沒有招到一個會React的人。大概,大家都覺得vue更好學吧。

我找了一篇很久以前的文章,記錄了自己初學React時的感受。

超性感的React Hooks(一):為何她獨具魅力

當時覺得React學習難,一度認為自己無法掌握好,是以還在寫文章勸大家學習angular[1]。現在想想真的有點點搞笑。

對初學者來說,React上手其實并不容易,那難在哪裡呢?以我自己的經驗總結一下:

生命周期難以了解,更難熟練運用

超性感的React Hooks(一):為何她獨具魅力

我們能夠相對容易的把生命周期記憶下來,但是運用到實踐裡卻是另外一回事。幾個運作時的生命周期了解起來更是不易。而如何做性能優化,這些生命周期又是重中之重。如果不小心,你寫的代碼甚至可能讓程式翻車。

能夠正确了解生命周期并熟練運用,是React開發者成為高手的必備條件。

可這,也是我們前進路上的第一條攔路虎。

成熟靠譜的元件化思維,形成困難

即使是擁有多年開發經驗的大佬,有可能元件化思維這一項也不過關。糟糕的元件劃分帶來的就是難以維護的糟糕代碼。

當然這不僅僅限制于React,所有的元件化思維架構,都會有同樣的挑戰。元件化思維非常重要,他是最底層的思維核心。更良好的元件化思維,寫出來的代碼必定更優雅,可維護性更高。反之,可能就是災難。

最火的狀态管了解決方案 Redux,概念多, 難以了解

超性感的React Hooks(一):為何她獨具魅力

Redux的思維非常優秀,可實際了解起來并不簡單。再加上許多人學習Redux時,都是通過 Redux中文文檔[2],我認為它加深了學習的難度,學完之後反而懵逼!

特别是自學的同學,很可能會因為redux,而将React拒之門外。

高階元件了解起來不容易

React Hooks出來之前,高階元件是無論如何也必須要掌握好的知識點。

然而許多同學基礎知識不紮實,高階函數沒有搞明白,面向對象也有點小問題,在學習高階元件時自然也是似懂非懂。

// 傳入基礎元件作為參數
const withRouter = (Component) => {

  // 建立中間元件
  const C = (props) => {
    const { wrappedComponentRef, ...remainingProps } = props;
    return (
      <Route render={routeComponentProps => (
        // wrappedComponentRef 用來解決高階元件無法正确擷取到ref的問題
        <Component {...remainingProps} {...routeComponentProps} ref={wrappedComponentRef} />
      )} />
    )
  }

  C.displayName = `withRouter(${Component.displayName || Component.name})`;
  C.WrappedComponent = Component;
  C.propTypes = {
    wrappedComponentRef: PropTypes.func
  }

  // hoistStatics類似于Object.assign,用于解決基礎元件因為高階元件的包裹而丢失靜态方法的問題
  return hoistStatics(C, Component);
}

export default withRouter;           

複制

優秀的解決方案都在社群,許多人用React很長一段時間都無法知曉

React本身其實非常簡單,可是圍繞React的一系列解決方案,卻沒有途徑告知大家。學完了React,但不一定知道如何使用React實作一個走馬燈,也可能不知道使用React如何實作一個月曆。

比較熱門的Redux,React-router等,都不算是React的官方解決方案。更多的方案例如 redux chunk,redux saga等等,很多React學習者都不知道有這些東西。在這種情況下,學習成本就變相增加很多。

和以前相比,React hooks的出現讓React的學習成本降低了很多。具體展現為:

1.生命周期可以不用學。react hooks使用全新的理念來管理元件的運作過程。2.高階元件不用學。React hooks能夠完美解決高階元件想要解決的問題,并且更靠譜。3.redux不再是必須品。我們能夠通過其他方式管理元件狀态。

三、超棒的開發體驗

和class文法相比,函數元件一直都更受歡迎。但是以前函數元件無法維護自己的狀态,是以在很多時候不得不選擇class來實作目的。

React Hooks 讓函數元件維護内部狀态成為了可能。

在我看來,React Hooks,是能夠最快實作心中所想的開發方式。

四、與Typescript結合更簡單

我們幾乎不用關注React hooks元件與typescript如何結合使用。這是class元件不具備的優點。

群裡的許多朋友在學習typescript時,常常會非常困惑,如何将typescript應用與React中?這樣的問題在高階元件時疑惑可能更大。相信吃過這個苦的同學都深有體會。

即使知道如何解決,也并不是那麼簡單。例如我們試圖使用ts清晰的描述Demo元件props傳入的資料類型,不得不定義額外的interface。

import React from 'react';
import { connect } from 'net';

interface ConnectProps {
  dispatch: any,
  history: any
}

interface DemoProps {
  name: string,
  age: number
}

interface InjectedProps extends DemoProps, ConnectProps {}

@connect
export default class Demo() {
  get injected() {
    return this.props as 
  }
  render() {
    return (
      <div>hello, world.</div>
    )
  } 
}           

複制

React Hooks元件作為函數元件,幾乎不會有這樣的煩惱。他就和普通函數一樣,沒有新增額外的負擔。

總的來說,React Hooks是React開發體驗的一次全面提升,也是一次效率的革命。如果你正在使用React,卻還沒有用上React Hooks,我敢保證,對你而言,這是一次遺憾。

本着不裝逼不引戰的原則,本系列文章主觀上不針對vue/angular等前端架構發表其他發表任何意見和看法。如果有得意忘形,吹噓過度之處,請勿往這方面思考 ~

本系列文章的所有案例,都可以在下面的位址中檢視

https://github.com/advance-course/react-hooks

本系列文章為原創,請勿私自轉載,轉載請務必私信我

References

[1]

是以還在寫文章勸大家學習angular: https://juejin.im/post/57863fc27db2a200630b2312

[2]

Redux中文文檔: https://www.redux.org.cn/