Search code examples
javascriptreactjsreact-hooksshow-hide

Implement "show more, show less" in React component when using map for adding the components


Having this component:

import React from 'react';
import PropTypes from 'prop-types';
import './style.scss';

const MyComponent = ({ data }) => {
  return (
      <div className="main-div">
        {data.map((event, index) => (
          <div key={index} className="child-div">
            {event.message}
          </div>
        ))}
      </div>
  );
};

MyComponent.propTypes = {
  data: PropTypes.array
};

export default MyComponent;

There is a div for the whole component, having the class main-div. For each element we receive through props (data) we are creating a child, having the class child-div.

My question is:

Is there a way to show only the first child-div when the component is rendered, put a button "Show more" - and when this is clicked to show all the child divs? And the button name to change to "Show less" - when clicked again to return to initial state?

I have found some implementations of something similar but don't know how to put it to this structure. Here it is an example.


Solution

  • Use state to filter/slice your data:

    import React from 'react';
    import PropTypes from 'prop-types';
    import './style.scss';
    
    const MyComponent = ({ data }) => {
      const [expanded, setExpanded] = useState(false)
      const dataForDisplay = expanded ? data : data.slice(0, 10)
      return (
          <div className="main-div">
            {dataForDisplay.map((event, index) => (
              <div key={index} className="child-div">
                {event.message}
              </div>
            ))}
            <button type="button" onClick={() => setExpanded(!expanded)}>
              {expanded ? 'Show Less' : 'Show More'} 
            </button>
          </div>
      );
    };
    
    MyComponent.propTypes = {
      data: PropTypes.array
    };
    
    export default MyComponent;