首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从React "truncate text“组件上的属性派生状态

从React "truncate text“组件上的属性派生状态
EN

Stack Overflow用户
提问于 2019-03-22 17:17:35
回答 2查看 464关注 0票数 0

我是个新手,大约一周前才开始使用它。我试图在一个组件中开发一个截断的文本功能,但却陷入了一个常见的新手陷阱。

我有一个患者信息组件,它显示了人们的个人数据,如姓名、生日等。该组件在视觉上设计为固定宽度的卡片,当宽度超过卡片的宽度时,需要截断人名:

Original text Truncated text

(“截断”格式是非常具体的,我不能只使用CSS )

我通过props将人名和姓氏从父组件传递给子PatientName组件,后者封装并处理截断功能。这是我使用的代码:

代码语言:javascript
运行
复制
import './patient-name.css';

import React from 'react';
import PropTypes from 'prop-types';

const TRUNCATED_MAX_SURNAME_CHARS = 10;
const TRUNCATED_SURNAME_ELLIPSIS = '...';

const TRUNCATED_MAX_NAME_CHARS = 1;
const TRUNCATED_NAME_ELLIPSIS = '.';

class PatientName extends React.Component {
  constructor(props) {
    super(props);

    this.state = { name: props.name, surname: props.surname };

    this.$element = React.createRef();
    this.$name = React.createRef();
  }

  isOverflowing() {
    const elementRightPos = this.$element.current.getBoundingClientRect().right;
    const nameRightPos = this.$name.current.getBoundingClientRect().right;

    return nameRightPos > elementRightPos;
  }

  componentDidMount() {
    if (this.isOverflowing()) this.truncate();
  }

  truncate() {
    this.setState({
      name: `${this.props.name.substring(
        0,
        TRUNCATED_MAX_NAME_CHARS,
      )}${TRUNCATED_NAME_ELLIPSIS}`,
      surname: `${this.props.surname.substring(
        0,
        TRUNCATED_MAX_SURNAME_CHARS,
      )}${TRUNCATED_SURNAME_ELLIPSIS}`,
    });
  }

  render() {
    return (
      <h4 className="patient-name" ref={this.$element}>
        <span className="patient-surname">{this.state.surname}</span>
        &nbsp;
        <span ref={this.$name}>{this.state.name}</span>
      </h4>
    );
  }
}

PatientName.propTypes = {
  name: PropTypes.string,
  surname: PropTypes.string,
};

export default PatientName;

工作正常(目前我并不担心截断性能)……直到我在父组件中选择另一个患者。那么患者的名字就不会改变,它仍然会显示我通过props传递的之前的名字。

我知道问题是从属性派生状态,构造函数只被调用一次,之后状态永远不会刷新,等等,但是...这样做的正确“反应方式”是什么?

我来自一个棱角分明的背景,我仍在努力理解这一点。

谢谢!

PS:我正在使用React 16.6

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-22 17:27:31

如果道具改变,你需要更新你的状态:

代码语言:javascript
运行
复制
componenDidUpdate(prevProps, prevState) {
  if (prevProps.name !== this.props.name || prevProps.surname !== this.props.surname) {
    this.setState({name: this.props.name, surname: this.props.surname});
  }
  else if (prevState.name !== this.state.name || prevState.surname !== this.state.surname) {
    if (this.isOverflowing()) this.truncate();
  }
}

使用新的未截断的props更新状态和重新呈现的第一个if,并获得新的测量值。第二个if用于检查新的测量值,并在需要时进行截断。

票数 0
EN

Stack Overflow用户

发布于 2019-03-22 18:57:43

自React 16.3+以来,有了一个新的组件生命周期,它是一个名为getDerivedStateFromProps的静态方法,它返回状态,并在组件接收属性时触发

因此,在您的示例中,您可以这样使用它:

代码语言:javascript
运行
复制
static getDerivedStateFromProps(nextProps, state) {
   return ({
  ...state,
  name: `${nextProps.name.substring(
    0,
    TRUNCATED_MAX_NAME_CHARS,
  )}${TRUNCATED_NAME_ELLIPSIS}`,
  surname: `${nextProps.surname.substring(
    0,
    TRUNCATED_MAX_SURNAME_CHARS,
  )}${TRUNCATED_SURNAME_ELLIPSIS}`,
});
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55296335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档