Search code examples
javascriptreactjsarraysjsonnext.js

How to keep the first item of accordion group open by default in NextJS?


I've built an accordion component from scratch in NextJS. It's working perfectly. But I want to keep the first accordion item open by default. How to achieve this?

Here's the code:

Accordion Item

import { RiAddLine } from "@remixicon/react";
import { useState } from "react";

const AccordionItem = ({ question, answer, isOpen, toggle }:{ question:string, answer:string }) => {

  return(
    <div className='bg-gray-200 dark:bg-gray-800 flex flex-col w-full select-none'>
      <div className='flex items-center px-6 py-4 cursor-pointer' onClick={toggle}>
        <div className='grow'>
          <p className='text-lg font-semibold'>{question}</p>
        </div>
        <div className='grow-0'>
          <RiAddLine className={`size-6 transition-all duration-300 ease-in-out ${isOpen ? '-rotate-45' : 'rotate-0' }`} />
        </div>
      </div>
      <div className={`grid px-6 overflow-hidden ease-in-out ${isOpen ? 'accordion-animate-open pb-4' : 'accordion-animate' }`}>
        <div className='text-gray-500 dark:text-gray-300 min-h-0'><p>{answer}</p></div>
      </div>
    </div>
  )

}

export default AccordionItem

Accordion Group

const [isOpen, setIsOpen] = useState(null)

const toggleOpen = id => () => setIsOpen(
  isOpen => isOpen === id ? null : id,
);

{
  faqData.map(({question, answer}, index) => (
    <AccordionItem
      question={question} 
      answer={answer}
      isOpen={isOpen === index}
      toggle={toggleOpen(index)}
    />
  ))
}

Solution

  • If what you are trying to do is have the first item open by default when the page loads, you can initialize the state in the accordion group to the the first item index (0):

    Instead of:

    const [isOpen, setIsOpen] = useState(null)
    

    Just use:

    const [isOpen, setIsOpen] = useState(0)