所以现在有几次我需要根据渲染时计算的属性设置组件的状态。结果,组件有时会被重新渲染。这不是一个大问题,但它感觉hacky而不是“反应方式”。所以我想知道是否有人有更好的解决方案。
所以最近的例子是可扩展的文本组件。与airbnb上的评论元素相似
这很容易。但最后一部分是检测是否有任何溢出,如果没有必要则不显示“更多”选项。我想出的解决方案是检查scrollHeight是否大于clientHeight,并根据它设置一些状态。这是我的解决方案的简化版本。
import React, { Component, PropTypes } from 'react';
import classNames from 'classnames'
function isOverflowed(element) {
return element.scrollHeight > element.clientHeight;
}
export default class ExpandableText extends Component {
static propTypes = {
content: PropTypes.string,
maxHeight: PropTypes.number,
};
static defaultProps = {
isOpen: false,
maxHeight: 10,
}
constructor(props) {
super(props);
this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
isOpen: props.isOpen,
isOverFlowed: true,
};
}
componentDidMount() {
if (!isOverflowed(this.refs.content)) {
this.setState({ isOpen: true, isOverFlowed: false });
}
}
handleOpen() {
this.setState({ isOpen: true });
}
handleClose() {
this.setState({ isOpen: false });
}
render() {
const { content, maxHeight } = this.props;
const { isOpen, isOverFlowed } = this.state;
const contentClassName = classNames('expandable-text', {
'expandable-text__content--closed': !isOpen,
'expandable-text__content--open': isOpen,
});
const actionsClassName = classNames('expandable-text__actions', { hide: !isOverFlowed })
return (
<div className="expandable-text">
<div
ref="content"
className={contentClassName}
style={{
maxHeight: isOpen ? 'none' : `${maxHeight}rem`,
}}
>
<p>{content}</p>
</div>
<div className={actionsClassName}>
<button onClick={isOpen ? this.handleClose : this.handleOpen}>{isOpen ? 'Close': 'Open'}</button>
</div>
</div>
);
}
}
所以有一个不错的数量,但重要的是在componentDidMount
我正在检查溢出,然后根据它设置状态(可能)。
现在我意识到这可能是通过允许限制字符数而不是高度或其他解决方案来实现的。但是,如果我们假设解决方案类似于此,那么有更多的反应方式吗? (这不需要重新渲染)
答案 0 :(得分:0)
这很好!您必须先渲染文本,然后才能检测到它是否会溢出。
你可以做一些像计算字符/行一样的hacky东西。但是每个客户的字体大小差别很大,所以你最终会得到一个好的&#34;猜测溢出大小。
另一件事是首先将文本&#34; off canvas&#34;,某种方式/用户无法看到的地方,放入一个与目标容器行为相同的容器中。然后测量溢出并开始渲染到实际容器,知道它将/不会溢出。