我編寫出色 React 組件的秘訣
我有一個懺悔。我不會為我的 React 組件編寫單個測試。是的,你沒看錯,不是一個。你可能想知道我如何跟踪包含許多組件的複雜 React 項目。這是我的訣竅:
始終編寫無需滾動即可閱讀的 React 組件。
根據經驗,如果你不滾動就無法閱讀 React 組件,那麼我敢打賭它不止做一件事。它有不止一個責任,不止一個目的。
在 React 中思考
這是來自 React 文檔的實際引用,顯然每個人都忘記閱讀了。
如果您遵循此建議,您編寫的每個組件都將只做一件事,僅用於一個目的。如果它最終增長,它應該被分解成更小的子組件。
操作數據的複雜函數呢?這也很簡單:我只是創建了一個包含所有邏輯的純函數,將其保存在一個文件中,然後在我的 React 組件中使用它。
讓我們看看一些代碼
假設我想將 React Context 添加到我的組件之一。
const AwesomeComponent = (props) => {
const defaults = {
mode: 'dark',
};
const cache = {
mode: local.get('theme.mode'),
};
const initialTheme = merge(defaults, cache);
const [theme, setTheme] = useState(initialTheme);
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div className="awesome-component">
<div>everything else...</div>
</div>
</ThemeContext.Provider>
);
};
組件的第一部分使用 useState
反應鉤子。它還使用從一些選項緩存值中獲取的一些默認值來初始化狀態。
第一次改進
默認值可以隨著時間的推移真正增長到許多其他選項,而不僅僅是 mode
.讓我們創建一個初始化狀態的函數。這個函數只有一個目的:初始化狀態。
const AwesomeComponent = (props) => {
const [theme, setTheme] = useState(themable());
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div className="awesome-component">
<div>everything else...</div>
</div>
</ThemeContext.Provider>
);
};
第二次改進
該組件仍然比它應該做的更多。讓我們將難以閱讀的 React 上下文代碼移動到一個單獨的組件中,然後在我們的主組件中實現它。這樣我們就不會關心上下文是如何初始化的,我們只關心上下文是初始化的。
const AwesomeComponent = (props) => {
return (
<Theme>
<div className="awesome-component">
<div>everything else...</div>
</div>
</Theme>
);
};
更多改進
如果你在 React 中開始這樣思考,你會注意到項目中到處都有這些小的變化。而且你的項目會越來越好。
最後的想法
代碼混亂
我們都為此感到內疚。初級開發者、高級開發者、全棧開發者。我們都在 OOP 或大型 React 組件中編寫了上帝類,而沒有按目的拆分它們。
但這必須改變,否則你正在從事的複雜項目將成為一個複雜的怪物項目。
它必須迅速改變。所以下次你打算寫一些 React 組件、鉤子或者只是一個簡單的函數時:為什麼不把它分成多個文件,每個文件都有一個職責呢?編程的世界會變得更好。