一個篩選組件如下圖:

篩選組件包含一個 button 和一個 form,button 能控制 form 的顯示與隱藏,設計里 button 和 form 在一行,實作時理所當然地把這一行封裝成了一個組件,
但在另一個專案里,設計有區別,button 被放到了面板的右上角,之前寫的組件沒法復用了,

看看之前封裝的組件:
function FilterBar() {
const [showForm, setShowForm] = useState(true);
return (
<div className="container">
<button
onClick={() => setShowForm(pre => !pre)}
>
{showForm ? "<<< Filter" : "Filter >>>"}
</button>
{showForm && (
<form>
<label>
Name <input />
</label>
<label>
IP <input />
</label>
</form>
)}
</div>
);
}
它做了以下 4 件事:
- 創建
button, - 創建
form, - 實作
button和form的聯動, - 創建容器
div.container, 對button和form布局,
「創建容器 div.container, 對 button 和 form 布局」這件事導致了組件沒法在新專案里復用,
能不能寫一個組件,不對子元素布局,把布局的作業交給組件使用者去做?
思路:把 div.container 去掉,把 button 和 form 的實體回傳,組件變成了一個 hook,
function useFilterBar() {
const [showForm, setShowForm] = useState(true);
return [
<button
onClick={() => setShowForm(pre => !pre)}
>
{showForm ? "<<< Filter" : "Filter >>>"}
</button>,
showForm ? (
<form>
<label>
Name <input />
</label>
<label>
IP <input />
</label>
</form>
) : (
undefined
)
];
}
function App() {
const [filterBtn, filterForm] = useFilterBar();
return (
<div className="card">
<Header title="Users">{filterBtn}</Header>
{filterForm}
<table>
<thead>
<tr>
<th>Name</th>
<th>IP</th>
</tr>
</thead>
<tbody>...</tbody>
</table>
</div>
);
}
class 組件沒法用 hook 怎么辦?
思路:使用高階組件,高階組件是函陣列件,可以使用 hook,然后把 button 和 form 通過 props 傳遞給 class 組件,
const withFilterBar = Cmp => props => {
const [filterBtn, filterForm] = useFilterBar();
return (
<Cmp
{...props}
filterBtn={filterBtn}
filterForm={filterForm}
/>
);
};
我寫這篇文章的目的不是為了記錄技巧,而是希望對組件有新的思考:把「子元素關聯關系 - 邏輯」和「子元素布局 - 視圖」兩件事拆開,讓組件更靈活,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/137746.html
標籤:JavaScript
