重構圖書搜索應用程序和獨立組件,第 3 部分
在第 2 部分之前,我們已經創建了一個圖書搜索應用程序並處理了加載和錯誤狀態。現在我們將了解如何將應用程序結構拆分為組件。
我們在 App.js
中編寫了整個應用程序 .它仍然是一個小例子,因此沒有必要將其拆分為文件夾。這篇文章將只展示如何拆分大型應用程序,而不會導致以後調試混亂。
文件夾結構沒有通用的最佳實踐,主要取決於兩個因素
- 項目有多大?
- 您的團隊有多大?
對於大型項目和大型團隊,基於功能或域的文件夾結構將運行良好。
對於小型項目,基於文件類型的文件夾結構將很容易工作。
你可以在這裡閱讀更多關於它的反應文檔
我個人的看法是,僅在需要時保持簡單、平坦和可擴展。當每個文件的長度增加時,您應該始終重構為複雜的文件夾結構。
讓我們繼續代碼,
在我們的圖書搜索應用程序中,我們可以創建這些組件
- 圖書搜索表單
- 加載器
- 書單
- 書籍
讓我們創建一個組件文件夾,並為我們的組件創建三個 JS 文件。
// booksSearchForm.js
import React from 'react';
const BookSearchForm = ({
onSubmitHandler,
searchTerm,
onInputChange,
error,
}) => {
return (
<form onSubmit={onSubmitHandler}>
<label>
<span>Search for books</span>
<input
type="search"
placeholder="microservice, restful design, etc.,"
value={searchTerm}
onChange={onInputChange}
required
/>
<button type="submit">Search</button>
</label>
{error && (
<div style={{ color: `red` }}>
some error occurred, while fetching api
</div>
)}
</form>
);
};
export default BookSearchForm;
我們已將組件拆分為自己的文件,並將必要的函數和狀態值作為 props 傳遞。
現在在 App.js 中
// App.js
import React, { useState } from 'react';
import axios from 'axios';
import BookSearchForm from './components/bookSearchForm';
import './App.css';
...
const App = () => {
...
return (
<section>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
{
loading && <div style={{color: `green`}}>fetching books for "<strong>{searchTerm}</strong>"</div>
}
...
</section>
)
}
讓我們以相同的方式拆分其他組件。
// Loader.js
import React from 'react';
const Loader = ({ loading, searchTerm }) => {
return (
<>
{loading && (
<div style={{ color: `green` }}>
fetching books for "<strong>{searchTerm}</strong>"
</div>
)}
</>
);
};
export default Loader;
至於 BooksList 和 Book 組件,我沒有拆分成文件放在同一個文件中。當功能增長時將其拆分。
// booksList.js
import React from 'react';
// Separate the UI specific transforming logic to utils folder
import { bookAuthors } from '../utils';
const Book = ({ book }) => {
return (
<li>
<div>
<img
alt={`${book.volumeInfo.title} book`}
src={`http://books.google.com/books/content?id=${
book.id
}&printsec=frontcover&img=1&zoom=1&source=gbs_api`}
/>
<div>
<h3>{book.volumeInfo.title}</h3>
<p>{bookAuthors(book.volumeInfo.authors)}</p>
<p>{book.volumeInfo.publishedDate}</p>
</div>
</div>
<hr />
</li>
);
};
const BooksList = ({ books }) => {
return (
<ul>
{books.items.map((book, index) => {
return <Book book={book} key={index} />;
})}
</ul>
);
};
export default BooksList;
並將所有這些添加到 App.js
return (
<>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
<Loader searchTerm={searchTerm} loading={loading} />
<BooksList books={books} />
</>
);
就是這樣,伙計們,我們已經成功地拆分了所有組件。我們可以通過移動狀態來進一步優化它。這是下一部分。
我們會看到,
- 如何管理狀態和
- 管理狀態的不同方式(自定義掛鉤、useReducer)
- 為什麼我們在 App.js 中管理所有狀態,而不是更詳細地管理組件本身
在這裡查看第 3 部分的代碼庫,整個系列的代碼庫可以參考這裡。
保持聯繫!
如果你喜歡這篇文章,你可以在 Twitter 上找到我以獲取更新、公告和新聞。 🐤
下一篇
使用自定義鉤子代替渲染道具