在 React.js 中实现“阅读更多”链接

问题描述 投票:0回答:7

我正在尝试实现一个

Read More
链接,该链接会展开以显示 单击后显示更多文本。我正在尝试以 React 方式做到这一点。

<!--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>
    );
  }

});

我是 React 新手。我不确定如何处理渲染方法中的所有内容。如何在纯 React 中实现此功能?

javascript html css dom reactjs
7个回答
10
投票

所以基本上你想根据状态属性“expanded”显示一个额外的 div。

您可以有条件地创建组件。如果你不想要一个组件,你可以直接返回 null。 我只想有一个小方法,例如:

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;
        }
    }
});

你的渲染函数应该变成:

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

每次调用

setState()
时,都会使用新状态触发
render()

如果 Expanded 为 false,您将返回 null 作为组件,这基本上意味着什么都没有。所以什么也不会显示。

当您单击链接时,它将更新您的状态和展开的值,因此您将返回一个 div 作为组件并将其显示。

我认为阅读this是一个好的开始。 这是一篇非常棒的文章,解释了渲染的基本工作原理以及与状态的链接。

您还应该确保您理解这种小示例 http://jsfiddle.net/3d1jzhh2/1/ 以了解状态和渲染如何相互链接。


4
投票

再次迟到回答,但也许有人会需要它。

所以基本上你只需要一个组件来接收你想要显示的文本。 然后,您将使用 useState 钩子来设置文本长度的值 - 是否需要显示短版本或长版本,最后一个函数将在文本的短版本和长版本之间切换。

代码示例:

import React, { useState } from 'react';

const ReadMore = ({text}) => {
  const [isReadMore, setIsReadMore] = useState(true);
  const toggleReadMore = () => {setIsReadMore(!isReadMore)};

  return (
    <p className='testimonials__quote__text'>
      {isReadMore ? text.slice(0, 150): text }
      // condition that will render 'read more' only if the text.length is greated than 150 chars
      {text.length > 150 &&
        <span onClick={toggleReadMore}>
          {isReadMore ? '...read more' : ' ...show less'}
        </span>
      }
    </p>
  )
}

export default ReadMore;

3
投票

您可以尝试 read-more-react 库,链接: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} 
/>

2
投票

你几乎走在正确的轨道上。正如反应文档中所述: https://facebook.github.io/react/tips/if-else-in-JSX.html

它只是使用经典的

if
和一个变量,如下所示:

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

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

1
投票

我知道我回答这个问题有点晚了,但为什么不只使用 1 个字符串而不是使用 2 个字符串呢?

查看这个 npm 包 https://www.npmjs.com/package/react-simple-read-more 它会解决问题。

如果您对代码感兴趣:https://github.com/oztek22/react-simple-read-more/blob/master/src/string-parser.jsx


0
投票

这就是 React Js 中的完整解决方案:

调用组件:

<TeamCard description="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." limit={150}/>

成分:

const TeamCard = ({ description, limit }) => {
  const [showAll, setShowAll] = useState(false);
  return (
    <p className="text-center text-white text-base pt-3 font-normal pb-5">
      {description.length > limit ? (
        <div>
          {showAll ? (
            <div>
              {description}
              <br />
              <button
                onClick={() => setShowAll(false)}
                className="text-primary"
              >
                Read Less
              </button>
            </div>
          ) : (
            <div>
              {description.substring(0, limit).concat("...")}
              <br />
              <button onClick={() => setShowAll(true)} className="text-primary">
                Read More
              </button>
            </div>
          )}
        </div>
      ) : (
        description
      )}
    </p>
  );
};
export default TeamCard;


0
投票

构建一个简单的组件(去掉样式)。

用途:

<ReadMore text={someLongText} maxChars={500} />

代码:

import React from "react";

interface ReadMoreProps extends React.HTMLAttributes<HTMLDivElement> {
  text: string;
  maxChars: number;
  readMoreText?: string;
  readLessText?: string;
}

const ReadMore = ({
  className,
  text,
  maxChars,
  readMoreText = "read more",
  readLessText = "read less",
}: ReadMoreProps) => {
  const [isExpanded, setIsExpanded] = React.useState(false);
  const hasReadMore = text.length > maxChars;

  return (
    <div className={className}>
      {text && (isExpanded || !hasReadMore) && (
        <p>
          {text}{" "}
          {hasReadMore && !!isExpanded && (
            <span
              onClick={() => setIsExpanded(false)}
            >
              {readLessText}
            </span>
          )}
        </p>
      )}
      {text && !isExpanded && !!hasReadMore && (
        <p>
          {text.slice(0, maxChars)}...{" "}
          <span
            onClick={() => setIsExpanded(true)}
          >
            {readMoreText}
          </span>
        </p>
      )}
    </div>
  );
};

export default ReadMore;
© www.soinside.com 2019 - 2024. All rights reserved.