DEV Community

Cover image for Mastering React Design Patterns: Create a Collapsible Text
Giuseppe Ciullo
Giuseppe Ciullo

Posted on • Edited on

Mastering React Design Patterns: Create a Collapsible Text

React developers often encounter the challenge of designing components that are both adaptable and reusable. . The Render Props pattern, one of many design patterns available, stands out as a valuable and flexible solution. In this article, we'll delve into the Render Props pattern within the context of a practical example: a collapsible text component featuring a "Show More" functionality.

Imagine you want to create a component that shows a short summary when closed and a more detailed version when opened. Traditional methods might involve complicated prop-passing, but the Render Props pattern provides a neater and more straightforward solution for this.

The Render Props Pattern

The Render Props pattern in React involves passing a function as a prop to a component. This function, usually named render, handles rendering content and is called within the component. This approach offers a neat and adaptable way to share code and state between components.

Collapsible Text Component

Let's dive into a practical example using TypeScript and React 18 syntax. Consider a CollapsibleText component that takes a renderText prop โ€“ a function deciding how the text should appear based on the component's state.

// CollapsibleText.tsx
import React, { useState } from 'react'

interface CollapsibleTextProps {
  renderText: (isExpanded: boolean) => React.ReactNode
}

export default function CollapsibleText({ renderText }: CollapsibleTextProps) {
  const [isExpanded, setIsExpanded] = useState(false)

  const toggleText = () => {
    setIsExpanded((prevState) => !prevState)
  }

  return (
    <div>
      <div>{renderText(isExpanded)}</div>
      <button onClick={toggleText}>
        {isExpanded ? 'Show Less' : 'Show More'}
      </button>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

In this component, the renderText function is responsible for determining the text content based on the isExpanded state. This encapsulation of rendering logic allows for greater customization.

Now, let's use this component in the parent App component:

// App.tsx
import CollapsibleText from '@/components/CollapsibleText'

const getTexts = () => {
  const shortText =
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
  const additionalText =
    ' Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
  const longText = shortText + additionalText

  return { shortText, longText }
}

export default function App() {
  const { shortText, longText } = getTexts()

  return (
    <div>
      <h1>Collapsible Text Example</h1>
      <CollapsibleText
        renderText={(isExpanded) => <p>{isExpanded ? longText : shortText}</p>}
      />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

In this simple example, the getTexts function generates short and long text content. The CollapsibleText component uses the renderText prop to decide how the text should be displayed. This approach keeps things clear and easy to manage, even for those new to React.

Conclusion

With the Render Props pattern, React components become more straightforward and adaptable. This guide demonstrated the pattern using a practical example, creating a collapsible text component. By encapsulating rendering logic in a function passed as a prop, components become modular and customizable.

Github Repo: https://github.com/JBassx/render-props-demo
StackBlitz: https://stackblitz.com/~/github.com/JBassx/render-props-demo

LinkedIn: https://www.linkedin.com/in/josephciullo/

Top comments (0)