Rumah  >  Artikel  >  alat pembangunan  >  Langkah terperinci untuk merangkum Komposer Konteks React (kongsi)

Langkah terperinci untuk merangkum Komposer Konteks React (kongsi)

藏色散人
藏色散人ke hadapan
2021-12-20 13:57:252148semak imbas

Artikel ini ditulis oleh komposer ruangan tutorial untuk memperkenalkan kepada anda cara merangkumkan React Context Composer langkah demi langkah. Saya harap ia dapat membantu rakan yang memerlukan.

Bagaimanakah cara saya merangkum Komposer Konteks React langkah demi langkah?

Motivasi

React mempunyai banyak penyelesaian pengurusan negeri, seperti Redux, Mobx, Recoil, dll. Setakat ini, saya hanya mengalami Redux, dan saya fikir ia masih agak menyusahkan. Kerana saya biasanya menulis banyak Cangkuk, saya lebih suka menggunakan Pembekal Konteks dengan cangkuk useContext, yang menjadikannya lebih mudah untuk memisahkan dan menggabungkan keadaan. Di sini, kami tidak akan membincangkan kebaikan dan keburukan setiap penyelesaian pengurusan negeri, tetapi menumpukan pada masalah sarang berbilang lapisan yang dihadapi apabila menggunakan Konteks.

Gambar di bawah ialah beberapa kod yang diekstrak daripada projek taro react hooks ts yang saya tulis baru-baru ini. Saya membahagikan beberapa keadaan global (tujuan pemisahan adalah untuk mengurangkan pemaparan semula yang tidak perlu) dan kemudian menyarangkannya. Cara penulisan ini mengingatkan saya tentang perasaan dikuasai oleh neraka panggil balik, yang sangat tidak selesa. Oleh itu, saya terfikir untuk menyegel komponen pesanan tinggi sendiri dan "meratakan" struktur dari segi penulisan.

<LoadingContext.Provider value={{ loading, setLoading }}>
  <UserDataContext.Provider value={{ name: "ascodelife", age: 25 }}>
    <ThemeContext.Provider value={"light"}>
    {/* ....more Providers as long as you want */}
    </ThemeContext.Provider>
  </UserDataContext.Provider>
</LoadingContext.Provider>

Penyelesaian paling mudah

Di sini, saya dengan pantas menulis penyelesaian pertama, menggunakan reduceRight untuk melengkapkan sarang Penyedia.

Sebab reduceRight digunakan di sini dan bukannya reduce adalah kerana kita lebih terbiasa dengan susunan tulisan dari lapisan luar hingga lapisan dalam.

// ContextComposer.tsx
import React from &#39;react&#39;;
type IContextComposerProps = {
  contexts: { context: React.Context<any>; value: any }[];
};
const ContextComposer: React.FC<IContextComposerProps> = ({ contexts, children }) => {
  return (
    <>
      {contexts.reduceRight((child, parent) => {
        const { context, value } = parent;
        return <context.Provider value={value}>{child}</context.Provider>;
      }, children)}
    </>
  );
};
export default ContextComposer;
// App.tsx
<ContextComposer
  contexts={[
    { context: ThemeContext, value: "light" },
    { context: UserDataContext, value: { name: "ascodelife", age: 25 } },
    { context: LoadingContext, value: { loading, setLoading } },
  ]}>
    { children }
</ContextComposer>

Selepas pengalaman sebenar, saya mendapati bahawa walaupun ia boleh digunakan, pengalaman pembangunan sedikit lebih teruk. Masalahnya ialah nilai yang diluluskan apabila komponen memasuki parameter adalah dari jenis mana-mana, yang bermaksud bahawa pemeriksaan jenis statik ts ditinggalkan. Apabila menghantar parameter, memandangkan semakan jenis statik tidak akan dilakukan pada nilai, bukan sahaja tiada sebarang gesaan kod semasa menaip kod, tetapi ia juga boleh menyebabkan beberapa ralat masa jalan yang agak rendah. Ulasan buruk!

Pelan transformasi berdasarkan React.cloneElement()

Untuk mengubah penyelesaian di atas, saya beralih kepada fungsi yang agak tidak popular tetapi mudah digunakan - React. cloneElement(). Tidak banyak perkara yang perlu diberi perhatian tentang fungsi ini Terutamanya lihat pada tiga parameter inputnya Yang pertama ialah elemen induk, yang kedua ialah prop induk, dan yang ketiga ialah parameter yang selebihnya... kanak-kanak, kecuali bagi. parameter pertama Kecuali untuk ini, semua nilai lain adalah pilihan.

Contohnya:

<!-- 调用函数 -->
React.cloneElement(<div/>,{},<span/>);
<!-- 相当于创建了这样一个结构 -->
<div> 
    <span></span>
</div>

Kemudian mari kita mulakan transformasi Bingkai reduceRight kekal tidak berubah.

// ContextComposer.tsx
import React from &#39;react&#39;;
type IContextComposerProps = {
  contexts: React.ReactElement[];
};
const ContextComposer: React.FC<IContextComposerProps> = ({ contexts, children }) => {
  return (
    <>
      {contexts.reduceRight((child, parent) => {
        return React.cloneElement(parent,{},child);
      }, children)}
    </>
  );
};
export default ContextComposer;
// App.tsx
<ContextComposer
  contexts={[
      <ThemeContext.Provider value={"light"} />,
      <UserDataContext.Provider value={{ name: "ascodelife", age: 25 }} />,
      <LoadingContext.Provider value={{ loading, setLoading }} />,
  ]}>
    { children }
</ContextComposer>

Selepas transformasi, apabila kita melepasi parameter, nampaknya kita benar-benar mencipta komponen (sudah tentu, komponen itu sebenarnya dicipta, tetapi komponen itu sendiri tidak diberikan kepada Dom maya. rendering sebenar Apa yang naik ialah salinan klon). Pada masa yang sama, masalah semakan jenis statik nilai yang baru kita fokuskan juga telah diselesaikan.

petua: React.cloneElement(ibu bapa,{},anak) bersamaan dengan React.cloneElement(ibu bapa,{anak:anak}), adakah anda tahu mengapa?

Sumber berkaitan

Kod sumber telah disegerakkan ke github (https://github.com/ascodelife/react-context-provider-composer).

Ia juga telah dibungkus dalam gudang npm (https://www.npmjs.com/package/@ascodelife/react-context-provider-composer).

Atas ialah kandungan terperinci Langkah terperinci untuk merangkum Komposer Konteks React (kongsi). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam