首頁  >  文章  >  web前端  >  ReactJS 設計模式:編寫健全且可擴展的元件

ReactJS 設計模式:編寫健全且可擴展的元件

WBOY
WBOY原創
2024-09-10 14:30:42208瀏覽

ReactJS Design Patterns: Writing Robust and Scalable Components

ReactJS 中的設計模式為應用程式開發中的常見問題提供了標準化且經過驗證的解決方案。使用這些模式不僅使您的程式碼更具可讀性和可維護性,而且還增強了其可擴展性和健壯性。讓我們深入研究一些最受歡迎的 ReactJS 設計模式,並透過範例來說明它們的用法。

1. 容器和表示組件模式

容器和展示模式將組件分為兩類:

  • 展示元件:專注於事物的外觀(UI)。
  • 容器組件:專注於事物如何運作(邏輯和狀態管理)。

這種分離可以實現更好的可重複使用性、更容易的測試和更清晰的程式碼。

範例:展示與容器組件

// Presentational Component: Displaying User List (UserList.js)
import React from 'react';

const UserList = ({ users }) => (
  <ul>
    {users.map((user) => (
      <li key={user.id}>{user.name}</li>
    ))}
  </ul>
);

export default UserList;
// Container Component: Fetching User Data (UserContainer.js)
import React, { useState, useEffect } from 'react';
import UserList from './UserList';

const UserContainer = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await response.json();
      setUsers(data);
    };
    fetchUsers();
  }, []);

  return <UserList users={users} />;
};

export default UserContainer;

這裡,UserList 是一個展示元件,它接收使用者作為 props,而 UserContainer 則處理資料擷取和狀態管理。

2. 高階組件(HOC)模式

A 高階組件 (HOC) 是一個將組件作為參數並傳回新組件的函數。 HOC 通常用於橫切關注點,例如驗證、日誌記錄或增強元件行為。

範例:建立 HOC 進行授權

// withAuthorization.js (HOC for Authorization)
import React from 'react';

const withAuthorization = (WrappedComponent) => {
  return class extends React.Component {
    componentDidMount() {
      if (!localStorage.getItem('authToken')) {
        // Redirect to login if not authenticated
        window.location.href = '/login';
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default withAuthorization;
// Dashboard.js (Component Wrapped with HOC)
import React from 'react';
import withAuthorization from './withAuthorization';

const Dashboard = () => <h1>Welcome to the Dashboard</h1>;

export default withAuthorization(Dashboard);

透過使用 withAuthorization 包裝 Dashboard,您可以確保只有經過驗證的使用者才能存取它。

3. 渲染道具模式

Render Props 模式涉及使用值為函數的 prop 在元件之間共用程式碼。此模式對於基於特定條件或狀態的動態渲染非常有用。

範例:使用渲染道具進行滑鼠追蹤

// MouseTracker.js (Component with Render Props)
import React, { useState } from 'react';

const MouseTracker = ({ render }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setPosition({ x: event.clientX, y: event.clientY });
  };

  return <div onMouseMove={handleMouseMove}>{render(position)}</div>;
};

export default MouseTracker;
// App.js (Using Render Props)
import React from 'react';
import MouseTracker from './MouseTracker';

const App = () => (
  <MouseTracker
    render={({ x, y }) => (
      <h1>
        Mouse position: ({x}, {y})
      </h1>
    )}
  />
);

export default App;

MouseTracker 元件使用 render prop 將滑鼠位置資料傳遞給任何元件,使其具有高度可重複使用性。

4. 自訂掛鉤模式

自訂 Hook 可讓您跨多個元件封裝和重複使用有狀態邏輯。這種模式促進了程式碼的可重用性和清晰的關注點分離。

範例:建立用於取得資料的自訂掛鉤

// useFetch.js (Custom Hook)
import { useState, useEffect } from 'react';

const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(url);
      const result = await response.json();
      setData(result);
      setLoading(false);
    };
    fetchData();
  }, [url]);

  return { data, loading };
};

export default useFetch;
// App.js (Using the Custom Hook)
import React from 'react';
import useFetch from './useFetch';

const App = () => {
  const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');

  if (loading) return <div>Loading...</div>;

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
};

export default App;

useFetch 自訂鉤子封裝了資料取得邏輯,可以在不同元件之間重複使用。

5. 複合組件模式

複合元件模式允許元件一起工作來管理狀態和行為。此模式對於建立複雜的 UI 元件(如選項卡、手風琴或下拉式選單)非常有用。

範例:使用複合組件建立選項卡

// Tabs.js (Parent Component)
import React, { useState } from 'react';

const Tabs = ({ children }) => {
  const [activeIndex, setActiveIndex] = useState(0);

  return React.Children.map(children, (child, index) =>
    React.cloneElement(child, { isActive: index === activeIndex, setActiveIndex, index })
  );
};

const Tab = ({ children, isActive, setActiveIndex, index }) => (
  <button onClick={() => setActiveIndex(index)}>{children}</button>
);

const TabPanel = ({ children, isActive }) => (isActive ? <div>{children}</div> : null);

Tabs.Tab = Tab;
Tabs.TabPanel = TabPanel;

export default Tabs;
// App.js (Using Compound Components)
import React from 'react';
import Tabs from './Tabs';

const App = () => (
  <Tabs>
    <Tabs.Tab>Tab 1</Tabs.Tab>
    <Tabs.Tab>Tab 2</Tabs.Tab>
    <Tabs.TabPanel>Content for Tab 1</Tabs.TabPanel>
    <Tabs.TabPanel>Content for Tab 2</Tabs.TabPanel>
  </Tabs>
);

export default App;

Tabs 元件管理狀態,而 Tab 和 TabPanel 元件則協同顯示選項卡內容。

6. 受控和非受控組件模式

受控元件完全由 React 狀態管理,而非受控元件則依賴 DOM 來取得狀態。兩者都有其用途,但為了一致性和可維護性,受控組件通常是首選。

範例:受控組件與不受控組件

// Controlled Component (TextInputControlled.js)
import React, { useState } from 'react';

const TextInputControlled = () => {
  const [value, setValue] = useState('');

  return (
    <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
  );
};

export default TextInputControlled;
// Uncontrolled Component (TextInputUncontrolled.js)
import React, { useRef } from 'react';

const TextInputUncontrolled = () => {
  const inputRef = useRef();

  const handleClick = () => {
    console.log(inputRef.current.value);
  };

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>Log Input Value</button>
    </>
  );
};

export default TextInputUncontrolled;

在受控元件中,React 完全控製表單狀態,而在非受控元件中,狀態由 DOM 本身管理。

7. 鉤子工廠模式

Hooks 工廠模式涉及建立動態產生和管理多個狀態或行為的鉤子,提供靈活的方式來管理複雜邏輯。

範例:使用 Hooks Factory 進行動態狀態管理

// useDynamicState.js (Hook Factory)
import { useState } from 'react';

const useDynamicState = (initialStates) => {
  const states = {};
  const setters = {};

  initialStates.forEach(([key, initialValue]) => {
    const [state, setState] = useState(initialValue);
    states[key] = state;
    setters[key] = setState;
  });

  return [states, setters];
};

export default useDynamicState;
// App.js (Using the Hooks Factory)
import React from 'react';
import useDynamicState from './useDynamicState';

const App = () => {
  const [states, setters] = useDynamicState([
    ['name', ''],
    ['age', 0],
  ]);

  return (
    <div>
      <input
        type="text"
        value={states.name}
        onChange={(e) => setters

.name(e.target.value)}
      />
      <input
        type="number"
        value={states.age}
        onChange={(e) => setters.age(parseInt(e.target.value))}
      />
      <p>Name: {states.name}</p>
      <p>Age: {states.age}</p>
    </div>
  );
};

export default App;

這個鉤子工廠動態創建和管理多個狀態,提供靈活性和更簡潔的程式碼。

結論

透過利用這些設計模式,您可以創建更健壯、可擴展和可維護的 React 應用程式。這些模式可協助您編寫符合最佳實務的乾淨、可重複使用的程式碼,確保您的應用程式隨著時間的推移更容易開發和管理。

您想更深入研究這些模式或探索其他主題嗎?

以上是ReactJS 設計模式:編寫健全且可擴展的元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:安全分配下一篇:安全分配