作為一名 React 開發者,你可能會面臨下面幾個問題:
為解決上述問題,下面介紹五種 React 組件設計模式,并對比它們的優缺點。
復合組件模式是一種通過將多個簡單組件組合在一起創建更復雜組件的方法。這種模式使得組件的邏輯分離,每個簡單組件負責特定的功能。通過復合組件,可以輕松構建可復用的、功能完備的組件。
如果想要設計一個定制化程度高,API方便理解的組件,可以考慮這個模式,這種模式不會出現多層Props傳遞的情況。
import React, { useState } from 'react';// 基礎按紐組件const Button = ({ label, onClick }) => ( <button onClick={onClick}>{label}</button>);// 基礎文本組件const TextBox = ({ value, onChange }) => ( <input type="text" value={value} onChange={onChange} />);// 復合組件const LoginPanel = () => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const handleLogin = () => { // 實現登錄邏輯 console.log(`Logging in with ${username} and ${password}`); }; return ( <div className="login-panel"> <TextBox value={username} onChange={(e) => setUsername(e.target.value)} /> <TextBox value={password} onChange={(e) => setPassword(e.target.value)} /> <Button label="Login" onClick={handleLogin} /> </div> );};// 使用示例const App = () => { return ( <LoginPanel /> );};export default App;
在這個例子中,LoginPanel 是一個復合組件,它包含了兩個基本組件 TextBox 和一個帶有登錄邏輯的 Button。
優點:
適用場景:
受控組件模式就是將組件轉換為受控組件,通過直接修改 Props 影響組件內部的狀態,一般在表單組件中比較常用。
import React, { useState } from 'react';const Button = ({ label, onClick }) => ( <button onClick={onClick}>{label}</button>);const TextBox = ({ value, onChange }) => ( <input type="text" value={value} onChange={onChange} />);// 受控組件模式的復合組件const ControlledLoginPanel = () => { const [loginData, setLoginData] = useState({ username: '', password: '' }); const handleInputChange = (e) => { const { name, value } = e.target; setLoginData((prevData) => ({ ...prevData, [name]: value, })); }; const handleLogin = () => { // 實現登錄邏輯 console.log(`Logging in with ${loginData.username} and ${loginData.password}`); }; return ( <div className="login-panel"> <TextBox value={loginData.username} onChange={handleInputChange} /> <TextBox value={loginData.password} placeholder="Password" /> <Button label="Login" onClick={handleLogin} /> </div> );};// 使用示例const App = () => { return ( <ControlledLoginPanel /> );};export default App;
在這個例子中,ControlledLoginPanel 組件就是一個受控組件的例子,其中的輸入框的值由 React 狀態管理。
優點:
適用場景:
自定義Hooks模式是一種將組件邏輯提取為可重用的函數的方法。將主要的邏輯轉移到一個Hooks中。用戶可以訪問這個Hooks,并公開了幾個內部邏輯(狀態、處理程序) ,使用戶能夠更好地控制組件。
import React, { useState } from 'react';const Button = ({ label, onClick }) => ( <button onClick={onClick}>{label}</button>);const TextBox = ({ value, onChange, placeholder }) => ( <input type="text" value={value} onChange={onChange} placeholder={placeholder} />);// 自定義 Hook,處理登錄表單邏輯const useLoginForm = () => { const [loginData, setLoginData] = useState({ username: '', password: '' }); const handleInputChange = (e) => { const { name, value } = e.target; setLoginData((prevData) => ({ ...prevData, [name]: value, })); }; const handleLogin = () => { // 在這里實現登錄邏輯 console.log(`使用用戶名 ${loginData.username} 和密碼 ${loginData.password} 登錄`); }; return { loginData, handleInputChange, handleLogin, };};// 在組件中使用自定義 Hookconst ControlledLoginPanel = () => { const { loginData, handleInputChange, handleLogin } = useLoginForm(); return ( <div className="login-panel"> <TextBox value={loginData.username} onChange={handleInputChange} placeholder="用戶名" /> <TextBox value={loginData.password} onChange={handleInputChange} placeholder="密碼" /> <Button label="登錄" onClick={handleLogin} /> </div> );};// 使用示例const App = () => { return ( <ControlledLoginPanel /> );};export default App;
在這個例子中,我們將與登錄表單相關的狀態和邏輯抽離到一個自定義 useLoginForm Hook 中。使得 ControlledLoginPanel 組件更專注于渲染 UI,減少了狀態和事件處理邏輯的混雜。
優點:
模式 3 中的自定義Hooks提供了很好的控制方式;但是比較難以集成,使用者需要按照組件提供的Hooks與State相結合進行編寫邏輯,提高了集成的復雜度。Props Getters模式則是通過簡化這一過程來實現。Getter是一個返回多個屬性的函數,它具有有意義的名稱,使得開發者能夠清楚地知道哪個Getter對應于哪個JSX元素。
import React, { useState } from 'react';const Button = ({ getLabel, handleClick }) => ( <button onClick={handleClick}>{getLabel()}</button>);const TextBox = ({ getValue, onChange, placeholder }) => ( <input type="text" value={getValue()} onChange={onChange} placeholder={placeholder} />);const ControlledLoginPanel = ({ getUsernameProps, getPasswordProps, handleLogin }) => { return ( <div className="login-panel"> <TextBox {...getUsernameProps()} placeholder="Username" /> <TextBox {...getPasswordProps()} placeholder="Password" /> <Button getLabel={() => 'Login'} handleClick={handleLogin} /> </div> );};// 使用 Props Getters 模式的 Hooksconst useLoginForm = () => { const [loginData, setLoginData] = useState({ username: '', password: '' }); const handleInputChange = (name) => (e) => { const { value } = e.target; setLoginData((prevData) => ({ ...prevData, [name]: value, })); }; const handleLogin = () => { // 實現登錄邏輯 console.log(`Logging in with ${loginData.username} and ${loginData.password}`); }; const getUsernameProps = () => ({ getValue: () => loginData.username, onChange: handleInputChange('username'), }); const getPasswordProps = () => ({ getValue: () => loginData.password, onChange: handleInputChange('password'), }); return { getUsernameProps, getPasswordProps, handleLogin, };};// 使用示例const App = () => { const { getUsernameProps, getPasswordProps, handleLogin } = useLoginForm(); return ( <ControlledLoginPanel getUsernameProps={getUsernameProps} getPasswordProps={getPasswordProps} handleLogin={handleLogin} /> );};export default App;
在這個例子中,我們基于模式 3 進行了改造,把 ControlledLoginPanel 組件需要的 Props 通過函數的方式進行獲取,以實現更靈活、更簡便的組件復用。
優點:
缺點:
適用場景:
State Reducer 模式是一種通過將組件的狀態更新邏輯委托給一個函數,實現更靈活的狀態管理方式。這種模式通常在處理復雜的狀態邏輯時非常有用。
import React, { useState } from 'react';const TextInput = ({ getInputProps }) => { const inputProps = getInputProps(); return <input {...inputProps} />;};const StateReducerExample = () => { // 初始狀態為一個空字符串 const [inputValue, setInputValue] = useState(''); // stateReducer 函數用于處理狀態的變化 const stateReducer = (state, changes) => { // 使用 switch case 處理不同的狀態變化情況 switch (Object.keys(changes)[0]) { // 如果變化的是 value 屬性 case 'value': // 如果輸入的字符數量超過 10 個,則不允許變化 if (changes.value.length > 10) { return state; } break; // 可以添加其他 case 處理不同的狀態變化 default: break; } // 返回新的狀態 return { ...state, ...changes }; }; // 獲取傳遞給子組件的 props const getInputProps = () => { return { value: inputValue, // 在輸入框變化時調用 stateReducer 處理狀態變化 onChange: (e) => setInputValue(stateReducer({ value: e.target.value })), }; }; return ( <div> <h3>State Reducer Example</h3> {/* 將獲取的 props 傳遞給 TextInput 組件 */} <TextInput getInputProps={getInputProps} /> </div> );};export default StateReducerExample;
在這個例子中,StateReducerExample 組件包含一個輸入框,通過 getInputProps 函數將輸入框的值和變化處理邏輯傳遞給 TextInput 組件。stateReducer 函數處理狀態的變化,確保輸入的字符數量不超過 10 個。
優點:
缺點:
適用場景:
通過這 5 種 React 組件設計模式,我們對“控制度”和“復雜度”有了更清晰的認識,下圖是復雜度和控制度的一個趨勢圖。
圖片
總體來說,設計的組件越靈活,功能也就越強大,復雜度也會更高。作為開發人員,建議大家根據自己的業務邏輯以及使用人群,靈活使用以上的設計模式。
React 組件設計模式
本文鏈接:http://www.www897cc.com/showinfo-26-59689-0.html淺析五種 React 組件設計模式
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com