1. 程式人生 > 實用技巧 >5個技巧助你編寫更好的React程式碼

5個技巧助你編寫更好的React程式碼

在本文中,我想分享幾個技巧,這些技巧將改善你的react程式碼。

1. 解構props

在js中解構物件(尤其是props)可以大大減少程式碼中的重複。看下面的例子:

//Parent Component
import react from 'react';

import CoffeeCard from './CoffeeCard';

const CafeMenu = () => {
    const coffeeList = [
        {
            id: '0',
            name: 'Espresso',
            price: '2.00',
            size: '16'
        },
        {
            id: '1',
            name: 'Cappuccino',
            price: '3.50',
            size: '24'
        },
        {
            id: '2',
            name: 'Caffee Latte',
            price: '2.70',
            size: '12'
        }
    ];

    return coffeeList.map(item => (
        <CoffeeCard key={item.id} coffee={item} />
    ));
};

export default CafeMenu;

CafeMenu元件用於儲存可用飲料的列表,現在我們想要建立另一個可以顯示一種飲料的元件。如果不對props進行解構,我們的程式碼將像下面這樣:

//Child Component
import React from 'react';

const CoffeeCard = props => {
    return (
        <div>
            <h1>{props.coffee.name}</h1>
            <p>Price: {props.coffee.price}$</p>
            <p>Size: {props.coffee.size} oz</p>
        </div
> ); }; export default CoffeeCard;

如你所見,它看起來並不好,每次我們需要獲取某個屬性時,都要重複props.coffee,幸運的是,我們可以通過解構來簡化它。

//Child Component (after destructuring props)
import React from 'react';

const CoffeeCard = props => {
    const { name, price, size } = props.coffee;
    return (
        <div>
            <h1>{name}</h1>
            <p>Price: {price}$</p>
            <p>Size: {size} oz</p>
        </div>
    );
};

export default CoffeeCard;

如果我們想將大量引數傳遞給子元件,我們還可以直接在建構函式(或函式元件的引數)中解構props。比如:

//Parent Component
import React from 'react';

import ContactInfo from './ContactInfo';

const UserProfile = () => {
    const name = 'John Locke';
    const email = '[email protected]';
    const phone = '01632 960668';

    return <ContactInfo name={name} email={email} phone={phone} />;
};

export default UserProfile;
//Child Component
import React from 'react';

const ContactInfo = ({ name, email, phone }) => {
    return (
        <div>
            <h1>{name}</h1>
            <p> E-mail: {email}</p>
            <p> Phone: {phone}</p>
        </div>
    );
};

export default ContactInfo;

2. 保持匯入模組的順序

有時(尤其是在“容器元件”中),我們需要使用許多不同的模組,並且元件匯入看上去有些混亂,如:

import { Auth } from 'aws-amplify';
import React from 'react';
import SidebarNavigation from './components/SidebarNavigation';
import { EuiPage, EuiPageBody } from '@elastic/eui';
import { keyCodes } from '@elastic/eui/lib/services';
import './index.css'
import HeaderNavigation from './components/HeaderNavigation';
import Routes from './Routes';

關於匯入模組的理想順序有很多不同的觀點。我建議多參考,然後找到適合你自己的那種。

至於我自己,我通常按型別對匯入進行分組,並按字母順序對它們進行排序(這是可選操作)。我也傾向於保持以下順序:

  1. 標準模組
  2. 第三方模組
  3. 自己程式碼匯入(元件)
  4. 特定於模組的匯入(例如css,PNG等)
  5. 僅用於測試的程式碼

快速重構一下,我們的模組匯入看上去舒服多了了。

import React from 'react';

import { Auth } from 'aws-amplify';
import { EuiPage, EuiPageBody } from '@elastic/eui';
import { keyCodes } from '@elastic/eui/lib/services';

import HeaderNavigation from './components/HeaderNavigation';
import SidebarNavigation from './components/SidebarNavigation';
import Routes from './Routes';

import './index.css'

3.使用Fragments

在我們的元件中,我們經常返回多個元素。一個React元件不能返回多個子節點,因此我們通常將它們包裝在div中。有時,這樣的解決方案會有問題。比如下面的這個例子中:

我們要建立一個Table元件,其中包含一個Columns元件。

import React from 'react';

import Columns from './Columns';

const Table = () => {
    return (
        <table>
            <tbody>
                <tr>
                    <Columns />
                </tr>
            </tbody>
        </table>
    );
};

export default Table;

Columns元件中包含一些td元素。由於我們無法返回多個子節點,因此需要將這些元素包裝在div中。

import React from 'react';

const Columns = () => {
    return (
        <div>
            <td>Hello</td>
            <td>World</td>
        </div>
    );
};

export default Columns;

然後就報錯了,因為tr標籤中不能放置div。我們可以使用Fragment標籤來解決這個問題,如下所示:

import React, { Fragment } from 'react';

const Columns = () => {
    return (
        <Fragment>
            <td>Hello</td>
            <td>World</td>
        </Fragment>
    );
};

export default Columns;

我們可以將Fragment視為不可見的div。它在子元件將元素包裝在標籤中,將其帶到父元件並消失。
你也可以使用較短的語法,但是它不支援key和屬性。

import React from 'react';

const Columns = () => {
    return (
        <>
            <td>Hello</td>
            <td>World</td>
        </>
    );
};
export default Columns;

4. 使用展示元件和容器元件

將應用程式的元件分為展示(木偶)元件和容器(智慧)元件。如果你不知道這些是什麼,可以下面的介紹:

展示元件

  • 主要關注UI,它們負責元件的外觀。
  • 資料由props提供,木偶元件中不應該呼叫API,這是智慧元件的工作
  • 除了UI的依賴包,它們不需要依賴應用程式
  • 它們可能包括狀態,但僅用於操縱UI本身-它們不應儲存應用程式資料。

木偶元件有:載入指示器,模態,按鈕,輸入。

容器元件

  • 它們不關注樣式,通常不包含任何樣式
  • 它們用於處理資料,可以請求資料,捕獲更改和傳遞應用程式資料
  • 負責管理狀態,重新渲染元件等等
  • 可能依賴於應用程式,呼叫Redux,生命週期方法,API和庫等等。
使用展示元件和容器元件的好處
  • 更好的可讀性
  • 更好的可重用性
  • 更容易測試

此外,它還符合“單一責任原則” - 一個元件負責外觀,另一個元件負責資料。

示例

讓我們看一個簡單的例子。這是一個BookList元件,該元件可從API獲取圖書資料並將其顯示在列表中。

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

const BookList = () => {
    const [books, setBooks] = useState([]);
    const [isLoading, setLoading] = useState(false);

    useEffect(() => {
        setLoading(true);
        fetch('api/books')
            .then(res => res.json())
            .then(books => {
                setBooks(books);
                setLoading(false);
            });
    }, []);

    const renderLoading = () => {
        return <p>Loading...</p>;
    };

    const renderBooks = () => {
        return (
            <ul>
                {books.map(book => (
                    <li>{book.name}</li>
                ))}
            </ul>
        );
    };

    return <>{isLoading ? renderLoading() : renderBooks()}</>;
};
export default BookList;

該元件的問題在於,它負責太多事情。它獲取並呈現資料。它還與一個特定的介面關聯,因此在不復制程式碼的情況下,不能使用此元件顯示特定使用者的圖書列表。

現在,讓我們嘗試將此元件分為展示元件和容器元件。

import React from 'react';

const BookList = ({ books, isLoading }) => {
    const renderLoading = () => {
        return <p>Loading...</p>;
    };

    const renderBooks = () => {
        return (
            <ul>
                {books.map(book => (
                    <li key={book.id}>{book.name}</li>
                ))}
            </ul>
        );
    };

    return <>{isLoading ? renderLoading() : renderBooks()}</>;
};
export default BookList;
import React, { useState, useEffect } from 'react';
import BookList from './BookList';

const BookListContainer = () => {
    const [books, setBooks] = useState([]);
    const [isLoading, setLoading] = useState(false);

    useEffect(() => {
        setLoading(true);
        fetch('/api/books')
            .then(res => res.json())
            .then(books => {
                setBooks(books);
                setLoading(false);
            });
    }, []);

    return <BookList books={books} isLoading={isLoading} />;
};

export default BookListContainer;

如你所見,它看起來要好得多。更重要的是,它使我們可以在具有不同資料的許多地方使用BookList元件。

豌豆資源搜尋網站https://55wd.com 電腦刺繡繡花廠 ttp://www.szhdn.com

5. 使用styled-components

對React元件進行樣式設定一直是個難題。查詢拼寫錯誤的類名,維護大型CSS檔案,處理相容性問題有時可能很痛苦。

styled-components是一個常見的css in js類庫,和所有同類型的類庫一樣,通過js賦能解決了原生css所不具備的能力,比如變數、迴圈、函式等。

要開始使用styled-components,你需要首先安裝依賴:

npm i styled-components

下面是一個示例:

import React from 'react';
import styled from 'styled-components';

const Grid = styled.div`
    display: flex;
`;

const Col = styled.div`
    display: flex;
    flex-direction: column;
`;

const MySCButton = styled.button`
    background: ${props => (props.primary ? props.mainColor : 'white')};
    color: ${props => (props.primary ? 'white' : props.mainColor)};
    display: block;
    font-size: 1em;
    margin: 1em;
    padding: 0.5em 1em;
    border: 2px solid ${props => props.mainColor};
    border-radius: 15px;
`;

function App() {
    return (
        <Grid>
            <Col>
                <MySCButton mainColor='#ee6352' primary>My 1st Button</MySCButton>
                <MySCButton mainColor='#ee6352'>My 2st Button</MySCButton>
                <MySCButton mainColor='#ee6352'>My 3st Button</MySCButton>
            </Col>
            <Col>
                <MySCButton mainColor='#515052' primary>My 4st Button</MySCButton>
                <MySCButton mainColor='#515052'>My 5st Button</MySCButton>
                <MySCButton mainColor='#515052'>My 6st Button</MySCButton>
            </Col>
        </Grid>
    );
}

export default App;

這只是樣式化元件如何工作的一個簡單示例,但是它們可以做的還遠遠不止這些。你可以在其官方文件中瞭解有關樣式化元件的更多資訊。