成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React 最佳實(shí)踐

lavnFan / 1109人閱讀

摘要:本文針對(duì)技術(shù)棧,總結(jié)了一些最佳實(shí)踐,對(duì)編寫高質(zhì)量的代碼有一定的參考作用。二最佳實(shí)踐說(shuō)明多用如果組件是純展示型的,不需要維護(hù)和生命周期,則優(yōu)先使用。理解并遵循這些最佳實(shí)踐,寫出來(lái)的代碼質(zhì)量會(huì)有一定的保證。

歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:

一、前言

在日常開(kāi)發(fā)和 Code Review 的時(shí)候,常常會(huì)發(fā)現(xiàn)一些共性的問(wèn)題,也有很多值得提倡的做法。本文針對(duì) React 技術(shù)棧,總結(jié)了一些最佳實(shí)踐,對(duì)編寫高質(zhì)量的代碼有一定的參考作用。

二、最佳實(shí)踐 & 說(shuō)明

多用 Function Component

如果組件是純展示型的,不需要維護(hù) state 和生命周期,則優(yōu)先使用 Function Component。它有如下好處:

代碼更簡(jiǎn)潔,一看就知道是純展示型的,沒(méi)有復(fù)雜的業(yè)務(wù)邏輯

更好的復(fù)用性。只要傳入相同結(jié)構(gòu)的 props,就能展示相同的界面,不需要考慮副作用。

更小的打包體積,更高的執(zhí)行效率

一個(gè)典型的 Function Component 是下面這個(gè)樣子:

function MenuItem({menuId, menuText, onClick, activeId}) {
    return (
        
{menuText}
); };

多用 PureComponent

如果組件需要維護(hù) state 或使用生命周期方法,則優(yōu)先使用 PureComponent,而不是 Component。Component 的默認(rèn)行為是不論 state 和 props 是否有變化,都觸發(fā) render。而 PureComponent 會(huì)先對(duì) state 和 props 進(jìn)行淺比較,不同的時(shí)候才會(huì) render。請(qǐng)看下面的例子:

class Child extends React.Component {
  render() {
    console.log("render Child");
    return (
      
{this.props.obj.num}
); } } class App extends React.Component { state = { obj: { num: 1 } }; onClick = () => { const {obj} = this.state; this.setState({obj}); } render() { console.log("render Parent"); return (
); } }

點(diǎn)擊按鈕后,Parent 和 Child 的 render 都會(huì)觸發(fā)。如果將 Child 改為 PureComponent,則 Child 的 render 不會(huì)觸發(fā),因?yàn)?props 還是同一個(gè)對(duì)象。如果將 Parent 也改為 PureComponent,則 Parent 的 render 也不會(huì)觸發(fā)了,因?yàn)?state 還是同一個(gè)對(duì)象。

遵循單一職責(zé)原則,使用 HOC / 裝飾器 / Render Props 增加職責(zé)

比如一個(gè)公用的組件,數(shù)據(jù)來(lái)源可能是父組件傳過(guò)來(lái),又或者是自己主動(dòng)通過(guò)網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)。這時(shí)候可以先定義一個(gè)純展示型的 Function Component,然后再定義一個(gè)高階組件去獲取數(shù)據(jù):

function Comp() {
    ...
}

class HOC extends PureComponent {

    async componentDidMount() {
        const data = await fetchData();
        this.setState({data});
    }
    
    render() {
        return ();
    }
}

組合優(yōu)于繼承

筆者在真實(shí)項(xiàng)目中就試過(guò)以繼承的形式寫組件,自己寫得很爽,代碼的復(fù)用性也很好,但最大的問(wèn)題是別人看不懂。我將復(fù)用的業(yè)務(wù)邏輯和 UI 模版都在父類定義好,子類只需要傳入一些參數(shù),然后再覆蓋父類的幾個(gè)方法就好(render的時(shí)候會(huì)用到)。簡(jiǎn)化的代碼如下:

class Parent extends PureComponent {
    componentDidMount() {
        this.fetchData(this.url);
    }
    
    fetchData(url) {
        ...
    }
    
    render() {
        const data = this.calcData();
        return (
            
{data} ); } } class Child extends Parent { constructor(props) { super(props); this.url = "http://api"; } calcData() { ... } }

這樣的寫法從語(yǔ)言的特性和功能實(shí)現(xiàn)來(lái)說(shuō),沒(méi)有任何問(wèn)題,最大的問(wèn)題是不符合 React 的組件編寫習(xí)慣。父類或者子類肯定有一方是不需要實(shí)現(xiàn) render 方法的,而一般我們看代碼都會(huì)優(yōu)先找 render 方法,找不到就慌了。另外就是搞不清楚哪些方法是父類實(shí)現(xiàn)的,哪些方法是子類實(shí)現(xiàn)的,如果讓其他人來(lái)維護(hù)這份代碼,會(huì)比較吃力。

繼承會(huì)讓代碼難以溯源,定位問(wèn)題也比較麻煩。所有通過(guò)繼承實(shí)現(xiàn)的組件都可以改寫為組合的形式。上面的代碼就可以這樣改寫:

class Parent extends PureComponent {
    componentDidMount() {
        this.fetchData(this.props.url);
    }
    
    fetchData(url) {
        ...
    }
    
    render() {
        const data = this.props.calcData(this.state);
        return (
            
{data} ); } } class Child extends PureComponent { calcData(state) { ... } render() { } }

這樣的代碼是不是看起來(lái)舒服多了?

如果 props 的數(shù)據(jù)不會(huì)改變,就不需要在 state 或者組件實(shí)例屬性里拷貝一份

經(jīng)常會(huì)看見(jiàn)這樣的代碼:

componentWillReceiveProps(nextProps) {
    this.setState({num: nextProps.num});
}

render() {
    return(
        
{this.state.num}
); }

num 在組件中不會(huì)做任何的改變,這種情況下直接使用 this.props.num 就可以了。

避免在 render 里面動(dòng)態(tài)創(chuàng)建對(duì)象 / 方法,否則會(huì)導(dǎo)致子組件每次都 render

render() {
    const obj = {num: 1}
    
    return(
        {...}} />
    );
}

在上面代碼中,即使 Child 是 PureComponent,由于 obj 和 onClick 每次 render 都是新的對(duì)象,Child 也會(huì)跟著 render。

避免在 JSX 中寫復(fù)雜的三元表達(dá)式,應(yīng)通過(guò)封裝函數(shù)或組件實(shí)現(xiàn)

render() {
    const a = 8;
    
    return (
        
{ a > 0 ? a < 9 ? ... : ... : ... }
); }

像上面這種嵌套的三元表達(dá)式可讀性非常差,可以寫成下面的形式:

f() {
    ...
}

render() {
    const a = 8;
    
    return (
        
{ this.f() }
); }

多使用解構(gòu),如 Function Component 的 props

const MenuItem = ({
    menuId, menuText, onClick, activeId,
}) => {
    return (
        ...
    );
};

定義組件時(shí),定義 PropTypes 和 defaultProps

例子如下:

class CategorySelector extends PureComponent {
    ...
}

CategorySelector.propTypes = {
    type: PropTypes.string,
    catList: PropTypes.array.isRequired,
    default: PropTypes.bool,
};

CategorySelector.defaultProps = {
    default: false,
    type: undefined,
};

避免使用無(wú)謂的標(biāo)簽和樣式

下面這種情況一般外層的div是多余的,可以將樣式直接定義在組件內(nèi),或者將定制的樣式作為參數(shù)傳入。例外:當(dāng)ServiceItem需要在多個(gè)地方使用,而且要疊加很多不一樣的樣式,原寫法會(huì)方便些。

// bad
// good
三、總結(jié)

本文列舉了筆者在項(xiàng)目實(shí)戰(zhàn)和 Code Review 過(guò)程中總結(jié)的 10 條最佳實(shí)踐,當(dāng)中的一些寫法和原則只代表個(gè)人立場(chǎng)。理解并遵循這些最佳實(shí)踐,寫出來(lái)的代碼質(zhì)量會(huì)有一定的保證。如果你有不同的意見(jiàn),或者有補(bǔ)充的最佳實(shí)踐,歡迎留言交流。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101570.html

相關(guān)文章

  • React 可視化開(kāi)發(fā)工具 shadow-widget 最佳實(shí)踐(上)

    摘要:上例的功能塊定義了如下節(jié)點(diǎn)樹(shù)入口節(jié)點(diǎn)是面板,結(jié)合該節(jié)點(diǎn)的函數(shù)書(shū)寫特點(diǎn),我們接著介紹最佳實(shí)踐如何處理功能塊之內(nèi)的編程。 本文介紹 React + Shadow Widget 應(yīng)用于通用 GUI 開(kāi)發(fā)的最佳實(shí)踐,只聚焦于典型場(chǎng)景下最優(yōu)開(kāi)發(fā)方法。分上、下兩篇講解,上篇概述最佳實(shí)踐,介紹功能塊劃分。 showImg(https://segmentfault.com/img/bVWu3d?w=6...

    techstay 評(píng)論0 收藏0
  • TypeScript 3.0 + React + Redux 最佳實(shí)踐

    摘要:首先聲明這篇文章是想說(shuō)明一下最新版本的的新特性帶來(lái)的極大的開(kāi)發(fā)體驗(yàn)提升而不是如何利用開(kāi)發(fā)應(yīng)用這個(gè)特性就是對(duì)的支持在的中有說(shuō)明具體可以參考這里在版本之前我們?cè)陂_(kāi)發(fā)應(yīng)用尤其是在配合一類庫(kù)的時(shí)候經(jīng)常用到諸如之類的封裝而這些函數(shù)其實(shí)都可以用裝飾器的 首先聲明, 這篇文章是想說(shuō)明一下最新版本的 TypeScript(3.0) 的新特性帶來(lái)的極大的 React 開(kāi)發(fā)體驗(yàn)提升. 而不是如何利用 Ty...

    CloudwiseAPM 評(píng)論0 收藏0
  • React Native項(xiàng)目時(shí)依賴管理的最佳實(shí)踐

    摘要:此時(shí)會(huì)把當(dāng)前路徑作為一個(gè)本地,在全局路徑下創(chuàng)建一個(gè)軟鏈接。所有依賴于全局路徑下的都必須是一個(gè)版本的,并沒(méi)有提供多版本號(hào)依賴的解決方法。因此,還是建議選擇一個(gè)常用的版本安裝在全局路徑,個(gè)別需求其他版本號(hào)的的項(xiàng)目,使用來(lái)配置局部依賴。 在實(shí)際開(kāi)發(fā)過(guò)程中,經(jīng)常需要同時(shí)運(yùn)行和修改多個(gè)React Native工程,比如運(yùn)行g(shù)ithub上的開(kāi)源項(xiàng)目以觀察某種控件的實(shí)際效果。那么此時(shí),各項(xiàng)目下的初始...

    AbnerMing 評(píng)論0 收藏0
  • React.js 最佳實(shí)踐(2016)_鏈接修正版

    摘要:譯者按最近依舊如火如荼相信大家都躍躍欲試我們團(tuán)隊(duì)也開(kāi)始在領(lǐng)域有所嘗試年應(yīng)該是逐漸走向成熟的一年讓我們一起來(lái)看看國(guó)外的開(kāi)發(fā)者們都總結(jié)了哪些最佳實(shí)踐年在全世界都有很多關(guān)于新的更新和開(kāi)發(fā)者大會(huì)的討論關(guān)于去年的重要事件請(qǐng)參考那么年最有趣的問(wèn)題來(lái)了我 譯者按:最近React(web/native)依舊如火如荼,相信大家都躍躍欲試,我們團(tuán)隊(duì)也開(kāi)始在React領(lǐng)域有所嘗試. 2016年應(yīng)該是Reac...

    syoya 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<