-1

When I was working with HTML content displayed with Read more and Read less(Show more or Show less) on my webpage, I struggled a lot googling to get a quick solution. Unfortunately, I failed to collect a single source of the solution. I started writing my own solution and decided to share my own solution if it helps someone.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
kazinayem2011
  • 348
  • 6
  • 20

1 Answers1

0

At first, You need to install "html-truncate"

npm i html-truncate

import React, {useState, useCallback, useEffect} from 'react';
import truncate from "truncate-html";

const ReadMoreMaster = (props) => {
    let {byWords,parentClass, readLess, readMore, length, ellipsis, spaceBefore} = props;
    const [showMore, setShowMore] = useState(false);

    truncate.setup({
        byWords: !!byWords,
        ellipsis: ellipsis ? ellipsis : '',
    })

    const [state, setState] = useState({
        showRealData: false,
        realData: props.children,
        truncatedData: truncate(props.children, length ? length : 2)
    });

    const handleShowData = useCallback(() => {
        setState(prevState => ({
            ...prevState,
            showRealData: !prevState.showRealData
        }));
    }, [setState]);

    useEffect(() => {
        if(byWords && props.children) {
            const textDetails = props.children.replace(/<[^>]+>/g, '');
            const arr = textDetails.split(" ");
            if(arr.length > length) {
                setShowMore(true);
            }
        }
    }, [byWords])

    return (
        <div className={parentClass}>
            <div
                dangerouslySetInnerHTML={{
                    __html: `${
                        !state.showRealData ? state.truncatedData : state.realData
                    }`
                }}
            />

            {spaceBefore === false ? '' : ' '}

            {
                showMore &&
                <a href={void (0)} className="read-more" onClick={handleShowData}>
                    {!state.showRealData ? readMore ? readMore : 'Read More' : readLess ? readLess : 'Read Less'}
                </a>
            }
        </div>
    );
};

export default ReadMoreMaster;

Now call the component like below:

<ReadMoreMaster
    byWords={true}
    length={150}
    ellipsis="..."
>
    <p>your content with or without HTML tag</p>
</ReadMoreMaster>

Supported props are:

// ...Supported Props...
// parentClass="test" || default value : null
// byWords={true} || default value : false
// ellipsis="..." || default value : null
// length={5} || default value : 2
// readMore="See More" || default value : Read More
// readLess="See less" || default value : Read Less
// spaceBefore={false} || default value : true

All done. Enjoy!!!

kazinayem2011
  • 348
  • 6
  • 20