如何將一個按鈕設定為控制所有手風琴的開關?
P粉391677921
2023-08-30 16:57:51
<p>我有一個組件,使用以下程式碼創建一個可折疊的手風琴:</p>
<pre class="brush:php;toolbar:false;">import React, {useState} from 'react';
const Collapsible = (props) =>{
const [open, setOpen] = useState(false);
const toggle = () => {
setOpen(!open);
}
return(
<div>
<button className={props.level} onClick={toggle}>{props.label}</button>
{open && (
<div className="toggle">
{props.children}
</div>
)}
</div>
)
}
export default Collapsible;</pre>
<p>我在主應用程式的多個位置使用它,有時在其他手風琴中使用手風琴。在多個實例中,我實際上不知道頁面上會有多少手風琴,因為它們是基於資料動態渲染的。考慮到這一點,我想在主應用程式中創建一個按鈕,打開(和關閉)所有手風琴,而不需要設置一個固定的數量,並且不需要在主應用程式中渲染所有手風琴(即一些手風琴在其他元件中渲染,然後匯入主應用程式)。 </p>
<p>我嘗試使用ref hooks來實現這一點:</p>
<ol>
<li>在Collapsible組件的按鈕中加入ref,並透過props從父組件存取:</li>
</ol>
<pre class="brush:php;toolbar:false;"><button className={props.level} onClick={toggle} ref={props.innerRef}>{props.label}</button> ;</pre>
<ol start="2">
<li>在主應用程式中加入以下ref:</li>
</ol>
<pre class="brush:php;toolbar:false;">const childRef = useRef();
const openClick = () => {
childRef.state = true;
}
const closeClick = () => {
childRef.state = false;
}</pre>
<ol start="3">
<li>在主應用程式中使用以下按鈕:</li>
</ol>
<pre class="brush:php;toolbar:false;"><button onClick = {openClick}>
展開全部
</button>
<button onClick = {closeClick}>
折疊全部
</button></pre>
<ol start="4">
<li>在渲染時將ref加入手風琴:</li>
</ol>
<pre class="brush:php;toolbar:false;"><Collapsible label="" level="content" innerRef={childRef}></pre>
<p>這實際上什麼都沒做,可能是因為我在第2步中嘗試訪問狀態的方式是錯誤的,但我認為這是值得一試的...</p>
<p>對於是否可行的任何想法嗎? </p>
您可以使用
Redux
。openAllAccordions
,循環遍歷ID,並將屬於該ID的手風琴設定為open=truecloseAllAccordions
,循環遍歷ID,並將屬於該ID的手風琴設定為open=false在一個更或多或少任意的元件實例集合中,需要一些協調是很常見的。我成功使用的一種方法是建立一個與關聯鉤子的Context,元件可以使用該鉤子進行註冊。此鉤子傳回共享狀態的視圖和修改該狀態的函數,以滿足您的需求。
在這裡,您可以建立一個儲存每個已註冊元件的
opener
函數並提供openAll
/closeAll
函數的Context:...還有一個被每個子元件呼叫的鉤子,用於在上下文中註冊,並傳回熟悉的
toggle
/open
值:還有一個用於執行批次操作的獨立鉤子也很方便:
Sandbox
#請注意,為簡單起見,這裡只是使用了單獨的
opener
(又稱setOpen
)函數作為每個已註冊元件的唯一識別碼。一個靈活的替代方案是使用其他標識符,這樣您可以在導航等情況下打開/關閉任意的手風琴。