Implementing a Read More link in React.js

25,868

Solution 1

So basically you want to display an extra div depending on the state property 'expanded'.

You can create a component conditionally. If you don't want a component you can just return null. I would just have a small method like:

var component = React.createClass({
    getInitialState: function() {
        return {
           expanded: false
       };
    },

    expandedText: function() {
        this.setState({
            expanded: true
        });       
    },

    getMoreTextDiv: function() {
        if (this.state.expanded) {
          return <div> My extended content </div>;
        } else {
          return null;
        }
    }
});

and your render function should become:

render: function() {
     var expandedDiv = this.getMoreTextDiv();
     return (
         <div>
             <a onClick={this.expandedText}>Read more</a>
             { expandedDiv }
         </div>
     );
}

Each time you call setState() you trigger render() using the new state.

If expanded is false you are going to return null as a component, which means basically, nothing. So nothing will be displayed.

When you click on your link it will update your state and the expanded value, so you will return a div as a component and it will be displayed.

I think a good start would be to read this. This is a really great article and explains how render basically works, and the link with state.

You should also make sure you understand this kind of small example http://jsfiddle.net/3d1jzhh2/1/ to see how state and render are linked with each other.

Solution 2

You can try the read-more-react library, link: https://www.npmjs.com/package/read-more-react

npm install --save read-more-react
import ReadMoreReact from 'read-more-react';


<ReadMoreReact 
        text={yourTextHere}
        min={minimumLength}
        ideal={idealLength}
        max={maxLength} 
/>

Solution 3

You're pretty much on the right track. As stated in the react docs here: https://facebook.github.io/react/tips/if-else-in-JSX.html

it's just using a classic if and a variable, like this:

render: function() {
    var expandedContent;
    if (this.state.expanded) {
        expandedContent = <div>some details</div>;
    }

    return (
       <div>
           <div>Title or likewise</div>
           {expandedContent}
       </div>
    );
}

Solution 4

I know I'm little late to answer this question but instead of using 2 strings why don't you do it by using just 1 string only.

check out this npm package https://www.npmjs.com/package/react-simple-read-more It'll solve the problem.

In case you are interested in code: https://github.com/oztek22/react-simple-read-more/blob/master/src/string-parser.jsx

Share:
25,868
Adi Sivasankaran
Author by

Adi Sivasankaran

Distributed systems. SRE. Cloud.

Updated on February 08, 2022

Comments

  • Adi Sivasankaran
    Adi Sivasankaran about 2 years

    I am trying to implement a Read More link, which expands to show more text after a click. I am trying to do this the React way.

    <!--html-->
    <div class="initialText">
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. 
      <a>
        Read More
      </a>
    </div>
    
    <div class="fullText">
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </div>
    

    /* JavaScript */
    /* @jsx DOM */
    var component = React.createClass({
    
      getInitialState: function() {
        return {
          expanded: false
        };
      },
    
      expandedText: function() {
        this.setState({
          expanded: true
        });       
      },
    
      render: function() {
        return (
          <div>
    
          </div>
        );
      }
    
    });
    

    I am new to React. I am not sure how to handle everything inside the render method. How can I implement this functionality in pure React?

  • Adi Sivasankaran
    Adi Sivasankaran about 9 years
    Would it be best to place the getMoreTextDiv() method inside the render method or as part of the React.createClass({ })?
  • Jeremy D
    Jeremy D about 9 years
    The method would be in createClass, but not in the render method. You could just have var expandedDiv = (this.state.expanded) ? <div>My content</div> : null; in render. I edited the answer.
  • Jeremy D
    Jeremy D about 9 years
    @ng-hacker did it help?
  • Adi Sivasankaran
    Adi Sivasankaran about 9 years
    Oh, yes. I implemented it. Thank you.
  • Negin Basiri
    Negin Basiri over 6 years
    I have the same question however my content is in a 'p' or a 'div' tag. I want to show 'Read more' if the height of text is more than 300px. It's super easy in jquery but no idea how to do it in react?
  • MMalke
    MMalke about 2 years
    Is adding a dependency on such a small library (38 stars as of today) for such a simple case really the best approach?
  • MMalke
    MMalke about 2 years
    Is adding a dependency on such a small library (0 stars as of today, 14 weekly downloads) for such a simple case really the best approach?