DEV Community

GihanRangana
GihanRangana

Posted on

3

Reactjs useAccordion Hook - How To Create And Use Accordions In React Js

Reactjs Accordion Hook - How To Create And Use Accordions In React Js

Unlock streamlined content organization in ReactJS with our in-depth tutorial on creating and utilizing custom Accordion Hooks. Elevate user experience by mastering the process of crafting and integrating accordions seamlessly into your React applications. Perfect for developers seeking efficient UI/UX solutions.

Follow this tutorial to create your own useAccordion hook in react js

useAccordion.ts
import { useState, useEffect, useCallback, useMemo } from "react"

const useAccordion = (steps: StepsType[], activeName: string): UseAccordionType => {

    const [activeIndex, setActiveIndex] = useState<number>(0)
    const [currentStep, setCurrentStep] = useState<StepsType>(steps[0])

    useEffect(() => {
        if (!activeName) return;

        steps.map((step, index) => {
            if (step.name === activeName) {
                setActiveIndex(index)
                setCurrentStep(step)
            }
        })

    }, [])

    const goNext = () => setActiveIndex((next) => next < steps.length ? next + 1 : steps.length)
    const goPrev = () => setActiveIndex((prev) => prev > 0 ? prev - 1 : 0)

    const handleHeaderClick = (index: number) => {
        setActiveIndex(index)
        setCurrentStep(steps[index])
    }

    const isActive = useCallback((index: number) => {
        return index === activeIndex
    }, [activeIndex])

    return useMemo(() => ({
        steps,
        activeIndex,
        currentStep,
        goNext,
        goPrev,
        handleHeaderClick,
        isActive
    }), [activeIndex, currentStep])
}

export default useAccordion;
Enter fullscreen mode Exit fullscreen mode
Accorion.tsx
const Accordion: React.FC<AccordionProps> = (props) => {

    const { steps } = props

    const renderContent = (step: StepsType, index: number) => {

        return (
            <React.Fragment key={`accordion-${index.toString()}-${step.name}`}>
                <div className={styles.accordionItem}>

                    <AccordionHeader {...props} step={step} index={index} />

                    <AccordionBody {...props} step={step} index={index} />

                </div>
            </React.Fragment>
        )
    }

    return (
        <div className={styles.accordion}>
            {steps && steps.map((step, index) => renderContent(step, index))}
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode
AccordionBody.tsx
const AccordionBody: React.FC<AccordionBodyProps> = (props) => {

    const { activeIndex, step, index } = props;

    const getClassNames = () => {

        const classes: string[] = [styles.accordionBody]

        if (activeIndex === index) classes.push(styles.active)

        return classes.join(' ')
    }

    return (
        <div
            className={getClassNames()}
        >
            {step.render && step.render(step)}
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode
AccordionHeader.tsx
const AccordionHeader: React.FC<AccordionHeaderProps> = (props) => {

    const { activeIndex, step, handleHeaderClick, index, isActive } = props

    const getClassNames = () => {

        const classes: string[] = [styles.accordionHeader]

        if (activeIndex === index) classes.push(styles.active)

        return classes.join(' ')
    }

    return useMemo(() => (
        <div
            className={getClassNames()}
            onClick={handleHeaderClick.bind(null, index)}
        >
            <span>{step.title}</span>

            <IoChevronForwardSharp
                className={[
                    styles.chevron,
                    isActive(index)
                        ? styles.chevronActive
                        : styles.chevronInactive
                ].join(' ')}
            />

        </div>
    ), [activeIndex])
}
Enter fullscreen mode Exit fullscreen mode
App.tsx
function App() {

    const steps: StepsType[] = [
        {
            name: "accordion1",
            title: "Accordion 1 Title",
            render: (props: any) => (
                <p>
                    {/*content*/}
                    Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae sit quod vero corrupti ducimus iste suscipit, culpa maiores minima sunt nobis adipisci expedita aliquid voluptatibus ab facere. Earum, distinctio quidem.
                </p>
            )
        },
        {
            name: "accordion2",
            title: "Accordion 2 Title",
            render: (props: any) => (
                <p>
                    Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, soluta quia odio dicta aspernatur vel, nesciunt repudiandae perspiciatis adipisci ipsum quae laborum minima praesentium iste modi doloremque officia saepe vitae!
                </p>
            )
        }
    ]

    const accordion = useAccordion(steps, 'accordion1')

    return (
        <div className="App">
            <Accordion {...accordion} />
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Follow the above video to get an idea about this source code.

Source: https://github.com/TheCodersLife/react-hook-useAccordion

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay