Rumah > hujung hadapan web > tutorial js > Prinsip SOLID dalam React: Kunci Menulis Komponen Boleh Diselenggara

Prinsip SOLID dalam React: Kunci Menulis Komponen Boleh Diselenggara

Susan Sarandon
Lepaskan: 2024-09-29 06:19:29
asal
702 orang telah melayarinya

SOLID Principles in React: The Key to Writing Maintainable Components

Apabila aplikasi React berkembang, keadaan boleh menjadi kucar-kacir dengan pantas—komponen kembung, kod yang sukar diselenggara dan pepijat yang tidak dijangka. Di situlah prinsip SOLID berguna. Asalnya dibangunkan untuk pengaturcaraan berorientasikan objek, prinsip ini membantu anda menulis kod yang bersih, fleksibel dan berskala. Dalam artikel ini, saya akan memecahkan setiap prinsip SOLID dan menunjukkan cara anda boleh menggunakannya dalam React untuk memastikan komponen anda teratur, kod anda lebih mudah diselenggara dan apl anda bersedia untuk berkembang.

SOLID ialah akronim yang bermaksud lima prinsip reka bentuk yang bertujuan untuk menulis kod yang bersih, boleh diselenggara dan berskala, pada asalnya untuk pengaturcaraan berorientasikan objek tetapi juga boleh digunakan dalam React:

S: Prinsip Tanggungjawab Tunggal: Komponen harus mempunyai satu kerja atau tanggungjawab.

O: Prinsip Terbuka/Tertutup: komponen hendaklah terbuka untuk sambungan **(mudah dipertingkat atau disesuaikan) tetapi **ditutup untuk pengubahsuaian (kod terasnya tidak perlu perubahan).

L: Prinsip Penggantian Liskov: komponen hendaklah boleh diganti oleh komponen anak mereka tanpa melanggar gelagat apl.

I: Prinsip Pengasingan Antara Muka: Komponen seharusnya tidak dipaksa untuk bergantung pada fungsi yang tidak digunakan.

D: Prinsip Penyongsangan Kebergantungan: Komponen harus bergantung pada abstraksi, bukan pelaksanaan konkrit.

Prinsip Tanggungjawab Tunggal (SRP)

Fikirkan seperti ini: Bayangkan anda mempunyai robot mainan yang hanya boleh melakukan satu kerja, seperti berjalan. Jika anda meminta ia melakukan perkara kedua, seperti bercakap, ia menjadi keliru kerana ia sepatutnya fokus pada berjalan! Jika anda mahu kerja lain, dapatkan robot kedua.

Dalam React, komponen hanya perlu melakukan satu perkara. Jika ia melakukan terlalu banyak, seperti mengambil data, mengendalikan input borang dan menunjukkan UI sekaligus, ia menjadi kucar-kacir dan sukar untuk diurus.

const UserCard = () => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch('/api/user')
      .then(response => response.json())
      .then(data => setUser(data));
  }, []);

  return user ? ( <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div> ) : <p>Loading...</p>;
};
Salin selepas log masuk

Di sini, UserCard bertanggungjawab untuk mengambil data dan memaparkan UI, yang melanggar Prinsip Tanggungjawab Tunggal.

const useFetchUser = (fetchUser) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser().then(setUser);
  }, [fetchUser]);

  return user;
};

const UserCard = ({ fetchUser }) => {
  const user = useFetchUser(fetchUser);

  return user ? (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  ) : (
    <p>Loading...</p>
  );
};

Salin selepas log masuk

Di sini, logik pengambilan data dialihkan ke cangkuk tersuai (useFetchUser), manakala UserCard memberi tumpuan semata-mata pada pemaparan UI dan mengekalkan SRP.

Prinsip Terbuka/Tertutup (OCP)

Fikirkan watak permainan video. Anda boleh menambah kemahiran baharu pada watak (sambungan) tanpa mengubah kebolehan teras mereka (pengubahsuaian). Itulah maksud OCP—membolehkan kod anda berkembang dan menyesuaikan diri tanpa mengubah apa yang sudah ada.

const Alert = ({ type, message }) => {
  if (type === 'success') {
    return <div className="alert-success">{message}</div>;
  }
  if (type === 'error') {
    return <div className="alert-error">{message}</div>;
  }
  return <div>{message}</div>;
};
Salin selepas log masuk

Di sini, setiap kali anda memerlukan jenis amaran baharu, anda perlu mengubah suai komponen Amaran, yang memecahkan OCP. apabila anda menambah pemaparan bersyarat atau menukar pemaparan kes dalam komponen anda, anda menjadikan komponen itu kurang boleh diselenggara, menyebabkan anda perlu menambah lebih banyak syarat dalam ciri dan mengubah suai kod teras komponen itu yang memecahkan OCP.

const Alert = ({ className, message }) => (
  <div className={className}>{message}</div>
);

const SuccessAlert = ({ message }) => (
  <Alert className="alert-success" message={message} />
);

const ErrorAlert = ({ message }) => (
  <Alert className="alert-error" message={message} />
);
Salin selepas log masuk

Kini, komponen Alert terbuka untuk sambungan (dengan menambahkan SuccessAlert, ErrorAlert, dll.) tetapi ditutup untuk pengubahsuaian kerana kita tidak perlu menyentuh komponen inti Alert untuk menambah jenis makluman baharu.

Mahukan OCP? Lebih suka gubahan daripada warisan

Prinsip Penggantian Liskov (LSP)

Bayangkan anda mempunyai telefon, dan kemudian anda mendapat telefon pintar baharu. Anda mengharapkan untuk membuat panggilan pada telefon pintar seperti yang anda lakukan dengan telefon biasa. Jika telefon pintar tidak dapat membuat panggilan, ia akan menjadi pengganti yang buruk, bukan? Itulah maksud LSP—komponen baharu atau kanak-kanak harus berfungsi seperti yang asal tanpa merosakkan sesuatu.

const Button = ({ onClick, children }) => (
  <button onClick={onClick}>{children}</button>
);

const IconButton = ({ onClick, icon }) => (
  <Button onClick={onClick}>
    <i className={icon} />
  </Button>
);
Salin selepas log masuk

Di sini, jika anda menukar Butang dengan Butang Ikon, anda kehilangan label, melanggar tingkah laku dan jangkaan.

const Button = ({ onClick, children }) => (
  <button onClick={onClick}>{children}</button>
);

const IconButton = ({ onClick, icon, label }) => (
  <Button onClick={onClick}>
    <i className={icon} /> {label}
  </Button>
);

// IconButton now behaves like Button, supporting both icon and label

Salin selepas log masuk

Kini, IconButton memanjangkan tingkah laku Button dengan betul, menyokong kedua-dua ikon dan label, supaya anda boleh menukarnya tanpa melanggar fungsi. Ini mengikut Prinsip Penggantian Liskov kerana kanak-kanak (IconButton) boleh menggantikan ibu bapa (Butang) tanpa sebarang kejutan!

Jika komponen B memanjangkan komponen A, di mana sahaja anda menggunakan komponen A, anda sepatutnya boleh menggunakan komponen B.

Prinsip Pengasingan Antara Muka (ISP)

Bayangkan anda menggunakan alat kawalan jauh untuk menonton TV. Anda hanya memerlukan beberapa butang seperti kuasa, kelantangan dan saluran. Jika alat kawalan jauh mempunyai banyak butang yang tidak diperlukan untuk pemain DVD, radio dan lampu, ia akan menjengkelkan untuk digunakan.

Andaikan anda mempunyai komponen jadual data yang memerlukan banyak prop, walaupun komponen yang menggunakannya tidak memerlukan kesemuanya.

const DataTable = ({ data, sortable, filterable, exportable }) => (
  <div>
    {/* Table rendering */}
    {sortable && <button>Sort</button>}
    {filterable && <input placeholder="Filter" />}
    {exportable && <button>Export</button>}
  </div>
);
Salin selepas log masuk

This component forces all consumers to think about sorting, filtering, and exporting—even if they only want a simple table.

You can split the functionality into smaller components based on what’s needed.

const DataTable = ({ data }) => (
  <div>
    {/* Table rendering */}
  </div>
);

const SortableTable = ({ data }) => (
  <div>
    <DataTable data={data} />
    <button>Sort</button>
  </div>
);

const FilterableTable = ({ data }) => (
  <div>
    <DataTable data={data} />
    <input placeholder="Filter" />
  </div>
);
Salin selepas log masuk

Now, each table only includes the functionality that’s needed, and you’re not forcing unnecessary props everywhere. This follows ISP, where components only depend on the parts they need.

Dependency Inversion Principle (DIP)

Imagine you're building with LEGO blocks. You have a robot built with specific pieces. But what if you want to swap out its arms or legs? You shouldn't have to rebuild the whole thing—just swap out the parts. The Dependency Inversion Principle (DIP) is like this: your robot (high-level) doesn't depend on specific parts (low-level); it depends on pieces that you can change easily.

const UserComponent = () => {
  useEffect(() => {
    fetch('/api/user').then(...);
  }, []);
  return <div>...</div>;
};
Salin selepas log masuk

This directly depends on fetch—you can’t swap it easily.

const UserComponent = ({ fetchUser }) => {
  useEffect(() => {
    fetchUser().then(...);
  }, [fetchUser]);
  return <div>...</div>;
};
Salin selepas log masuk

Now, the fetchUser function is passed in, and you can easily swap it with another implementation (e.g., mock API, or another data source), keeping everything flexible and testable.

Final Thoughts

Understanding and applying SOLID principles in React can drastically improve the quality of your code. These principles—Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion—help you write components that are more modular, flexible, and easier to maintain. By breaking down responsibilities, keeping code extensible, and making sure each part of your app interacts in predictable ways, you can create React applications that scale more easily and are simpler to debug. In short, SOLID principles lead to cleaner and more maintainable codebases.

Atas ialah kandungan terperinci Prinsip SOLID dalam React: Kunci Menulis Komponen Boleh Diselenggara. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan