Radix UI Accordion动态子组件下defaultValue属性不生效问题
Radix UI Accordion动态子组件下defaultValue不生效问题
问题描述
在Next.js项目中使用Radix UI的Accordion组件时,当子组件为动态生成时,defaultValue属性无法按预期工作——即使设置了defaultValue,手风琴项也不会默认展开。
代码片段
页面代码
<AccordionContextProvider> <div className="w-full"> <TotalIngresosThisMonth /> </div> <ClientSideAccordionManager> <AccordionContentWrapper itemId="item-1" title="Administrar ingresos"> {/* Content for item-1 */} </AccordionContentWrapper> <AccordionContentWrapper itemId="item-2" title="Administrar fuente de ingresos"> {/* Content for item-2 */} </AccordionContentWrapper> {/* Additional sections if needed */} </ClientSideAccordionManager> </AccordionContextProvider>
ClientSideAccordionManager组件代码
export const ClientSideAccordionManager: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { openItems, setOpenItems } = useAccordionContext(); const handleValueChange = (value: string[]) => { setOpenItems(value); }; return ( <Accordion type="multiple" defaultValue={["item-1"]} // 尝试设置item-1为默认展开项 value={openItems} onValueChange={handleValueChange} > {children} </Accordion> ); };
AccordionContentWrapper组件代码
"use client"; import { AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; import React from 'react'; export const AccordionContentWrapper: React.FC<{ itemId: string; title: string; children: React.ReactNode; }> = ({ itemId, title, children }) => { return ( <AccordionItem value={itemId}> <AccordionTrigger>{title}</AccordionTrigger> <AccordionContent>{children}</AccordionContent> </AccordionItem> ); };
预期行为
页面加载时,defaultValue中指定的手风琴项默认展开。
实际行为
无论指定什么defaultValue,手风琴都不会默认展开任何项。
问题原因与解决方案
原因
当为Radix UI Accordion同时设置value和defaultValue时,组件会进入受控模式,此时defaultValue会被完全忽略,组件状态完全由value控制。你的openItems(即传给value的值)初始状态应为空数组,因此没有默认展开项。
解决方案
方案1:在Context中设置初始值(推荐)
修改AccordionContextProvider的状态初始化逻辑,将openItems的初始值设为你想要默认展开的项数组,比如["item-1"]:
// 示例AccordionContextProvider代码 const AccordionContextProvider = ({ children }) => { // 初始值设为默认展开的项 const [openItems, setOpenItems] = useState<string[]>(["item-1"]); return ( <AccordionContext.Provider value={{ openItems, setOpenItems }}> {children} </AccordionContext.Provider> ); };
方案2:切换为非受控模式(无需全局状态时)
如果不需要通过Context全局管理手风琴展开状态,可去掉value和onValueChange属性,仅保留defaultValue:
export const ClientSideAccordionManager: React.FC<{ children: React.ReactNode }> = ({ children }) => { return ( <Accordion type="multiple" defaultValue={["item-1"]} > {children} </Accordion> ); };
内容的提问来源于stack exchange,提问作者Vladimirzb
相关产品推荐
相关产品推荐

