I'm using a react-accessible-accordion to present the user with a form one panel at a time. There is a "Reset" button that resets the impacts of any of the buttons the user may have pushed. The buttons are inside the panels. How do you programmatically collapse any open panels? There is the dangerouslySetExpanded option for an AccordionItem, but I don't see any practical examples of this being used or thorough documentation of the option (this is where that option is described in the docs). Do I have to use state variables here for the expanded-collapsed state of each item to be able to manipulate it programmatically? Here's a simplified version of the code I have now:
import React from 'react';
import ToggleButton from "react-bootstrap/ToggleButton";
import ButtonGroup from "react-bootstrap/ButtonGroup";
import 'bootstrap/dist/css/bootstrap.min.css';
import {Accordion, AccordionItem, AccordionItemHeading, AccordionItemButton, AccordionItemPanel} from 'react-accessible-accordion';
export const AccordionComponent = props => { stateHooks = [React.useState(-1), React.useState(-1)] const [ [varA, setVarA], [varB, setVarB] ] = stateHooks const handleResetAccordion = e => { e.preventDefault(); stateHooks.forEach(hook => { // pass -1 to each setter hook[1]('-1'); // index 1 contains the setter }) } return ( <div className="accordion_container"> <Accordion allowZeroExpanded={true}> <AccordionItem> <AccordionItemHeading> <AccordionItemButton> Panel #1 Title </AccordionItemButton> </AccordionItemHeading> <AccordionItemPanel> <div className='radioQuestionCard'> <h3>Question #1 Prompt:</h3> <ButtonGroup className='radio' toggle id='q1'> <ToggleButton key='0' type="radio" name="q1" value='0' checked={varA === '0'} onChange={e => setVarA(e.currentTarget.value)} > Q1: Option1 </ToggleButton> <ToggleButton key='1' type="radio" name="q1" value='1' checked={varA === '1'} onChange={e => setVarA(e.currentTarget.value)} > Q1: Option2 </ToggleButton> </ButtonGroup> </div> </AccordionItemPanel> </AccordionItem> <AccordionItem> <AccordionItemHeading> <AccordionItemButton> Panel #2 Title </AccordionItemButton> </AccordionItemHeading> <AccordionItemPanel> <div className='radioQuestionCard'> <h3>Question #2 Prompt:</h3> <ButtonGroup className='radio' toggle id='q2'> <ToggleButton key='0' type="radio" name="q2" value='0' checked={varB === '0'} onChange={e => setVarB(e.currentTarget.value)} > Q2: Option1 </ToggleButton> <ToggleButton key='1' type="radio" name="q2" value='1' checked={varB === '1'} onChange={e => setVarB(e.currentTarget.value)} > Q2: Option2 </ToggleButton> </ButtonGroup> </div> </AccordionItemPanel> </AccordionItem> </Accordion> <button className='btn btn-danger btn-sm' onClick={handleResetAccordion} id='resetAccordion'> Reset </button> </div> )
} 5 3 Answers
The react-accessible-accordion intentionally omits the ability to programmatically control the expanded state of the accordion panels, so a work-around I found is to put the whole accordion inside of a div, and give that div a key parameter. When the key changes, the accordion will be forcibly reinitialized.
let accordion_key = 12345;
const handleReinitialize = () => accordion_key++;
return( <div className="accordion_container" key={accordion_key}> <Accordion> <AccordionItem> <AccordionItemHeading> ... etc. <button onClick={handleReinitialize} id='reinitialize'>Reinitialize Accordion</button> </div>
) 4 I think you can just make it a boolean variable and change it programmatically. If its value is undefined, it will use the button state value.
<AccordionItem dangerouslySetExpanded={isExpanded}>
...
</AccordionItem>where isExpanded is set by a setState variable somewhere
const [ isExpanded, setIsExpanded ] = setState()const closeAll = () => { setIsExpanded(false)
} 1 For the older version you can try using the expanded prop of react accessible dropdown and then add and an onclick to a div element in the AccordionItemTitle.
<AccordionItem uuid="a" expanded={()=>this.setIsCollapse("a")}>
<AccordionItemTitle> <div onClick={(value)=>this.onChangeAccordion(value)}> </div>
</AccordionItemTitle>
</AccordionItem>