如何将一个按钮设置为控制所有手风琴的开关?
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
)函数作为每个已注册组件的唯一标识符。一个灵活的替代方案是使用其他标识符,这样您可以在导航等情况下打开/关闭任意的手风琴。