cari

Rumah  >  Soal Jawab  >  teks badan

Bagaimanakah saya boleh menetapkan butang untuk menghidupkan dan mematikan semua akordion?

<p>Saya mempunyai komponen yang mencipta akordion boleh lipat menggunakan kod berikut: </p> <pre class="brush:php;toolbar:false;">import React, {useState} daripada 'react'; const Boleh Dilipat = (props) =>{ const [open, setOpen] = useState(false); togol const = () => setOpen(!open); } kembali( <div> <button className={props.level} onClick={toggle}>{props.label}</button> {buka && <div className="togol"> {props.children} </div> )} </div> ) } eksport lalai Boleh Dilipat;</pre> <p>Saya menggunakannya di beberapa tempat dalam aplikasi utama dan kadangkala dalam akordion lain. Dalam beberapa keadaan, saya sebenarnya tidak tahu berapa banyak akordion yang terdapat pada halaman kerana ia dipaparkan secara dinamik berdasarkan data. Dengan ini, saya ingin mencipta butang dalam aplikasi utama yang menghidupkan (dan mematikan) semua akordion tanpa perlu menetapkan nombor tetap, dan tanpa perlu membuat semua akordion dalam aplikasi utama (iaitu beberapa akordion dalam komponen lain dan kemudian diimport ke dalam aplikasi utama). </p> <p>Saya cuba menggunakan cangkuk ref untuk mencapai ini: </p> <ol> <li>Tambahkan rujukan dalam butang komponen Boleh Dilipat dan aksesnya daripada komponen induk melalui prop: </li> </ol> <pre class="brush:php;toolbar:false;"><button className={props.level} onClick={toggle} ref={props.innerRef}>{props.label}</button> ;</pra> <ol start="2"> <li>Tambahkan rujukan berikut dalam aplikasi utama: </li> </ol> <pre class="brush:php;toolbar:false;">const childRef = useRef(); const openClick = () => childRef.state = benar; } const closeKlik = () => childRef.state = palsu; }</pre> <ol start="3"> <li>Gunakan butang berikut dalam aplikasi utama: </li> </ol> <pre class="brush:php;toolbar:false;"><butang onClick = {openClick}> Kembangkan Semua </butang> <butang onClick = {closeClick}> Runtuhkan semua </button></pre> <ol start="4"> <li>Tambahkan ref pada akordion semasa membuat persembahan: </li> </ol> <pre class="brush:php;toolbar:false;"><Collapsible label=""level="innerRef={childRef}></pre> <p>Ini sebenarnya tidak melakukan apa-apa, mungkin kerana cara saya cuba mengakses keadaan dalam langkah 2 adalah salah, tetapi saya fikir ia patut dicuba...</p> <p>Ada idea sama ada ini boleh dilakukan? </p>
P粉391677921P粉391677921453 hari yang lalu659

membalas semua(2)saya akan balas

  • P粉441076405

    P粉4410764052023-08-31 15:23:23

    Boleh guna Redux.

    1. Apabila anda membuat akordion, berikan mereka id tertentu dan simpan dalam storan.
    2. Buat kepinganopenAllAccordions, gelung melalui ID, dan tetapkan akordion kepunyaan ID itu kepada open=true
    3. Buat kepingancloseAllAccordions, gelung melalui ID, dan tetapkan akordion kepunyaan ID itu kepada open=false

    balas
    0
  • P粉809110129

    P粉8091101292023-08-31 12:37:09

    Dalam koleksi contoh komponen yang lebih kurang sewenang-wenangnya, adalah perkara biasa untuk memerlukan penyelarasan. Satu pendekatan yang saya gunakan dengan jayanya ialah mencipta Konteks dengan cangkuk berkaitan yang komponen boleh didaftarkan. Cangkuk ini mengembalikan pandangan keadaan kongsi dan fungsi yang mengubah suai keadaan itu agar sesuai dengan keperluan anda.

    Di sini anda boleh mencipta Konteks yang menyimpan opener函数并提供openAll/closeAllfungsi untuk setiap komponen yang didaftarkan:

    const AccordionProvider = ({ children }) => {
      const [openers] = useState(new Set());
    
      // 当创建时,是否应该展开新的可折叠项?
      //(支持递归展开是必要的)
      const [defaultOpen, setDefaultOpen] = useState(false);
    
      const register = useCallback(
        (opener) => {
          openers.add(opener);
          return () => openers.delete(opener); // 返回一个用于`useEffect`的取消注册函数
        },
        [openers]
      );
    
      const openAll  = useCallback(() => {
        setDefaultOpen(true);
        openers.forEach(opener => opener(true)),
      }, [setDefaultOpen, openers]);
    
      const closeAll = useCallback(() => {
        setDefaultOpen(false);
        openers.forEach(opener => opener(false)),
      }, [setDefaultOpen, openers]);
    
      return (
        <AccordionContext.Provider
          value={{ register, openAll, closeAll, defaultOpen }}
          children={children}
        />
      );
    };
    

    ...Terdapat juga cangkuk yang dipanggil oleh setiap komponen kanak-kanak untuk mendaftar dengan konteks dan mengembalikan nilai toggle/open yang biasa:

    const useAccordionAsClient = () => {
      const { register, defaultOpen } = useContext(AccordionContext);
    
      const [open, opener] = useState(defaultOpen);
      const toggle = useCallback(() => opener((open) => !open), [opener]);
    
      useEffect(() => register(opener), [register, opener]);
    
      return { toggle, open };
    };
    

    Terdapat juga cangkuk berasingan untuk melakukan operasi kelompok yang juga berguna:

    const useAccordionAsManager = () => {
      const { openAll, closeAll } = useContext(AccordionContext);
    
      return { openAll, closeAll };
    };
    

    Kotak pasir

    Sila ambil perhatian bahawa untuk kesederhanaan, fungsi opener(又名setOpen) yang berasingan digunakan di sini sebagai pengecam unik untuk setiap komponen yang didaftarkan. Alternatif yang fleksibel ialah menggunakan pengecam lain, supaya anda boleh membuka/menutup akordion sewenang-wenangnya semasa navigasi dsb.

    balas
    0
  • Batalbalas