我对React还是很陌生,大约一个星期前才开始使用它。我正在尝试在组件中开发截断文本功能,并陷入了似乎是常见的新手陷阱中。
我有一个患者信息组件,该组件显示人们的个人数据,例如姓名,出生日期等。该组件在视觉上设计为宽度固定的卡片,每当其宽度超过用户姓名的宽度时,都必须将其截断卡:
(“截断”格式非常具体,我不能仅使用CSS做到这一点)
我正在通过道具将人员的姓名和姓氏从父组件传递到子PatientName组件,该子组件封装并处理截断功能。这是我正在使用的代码:
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>
<span ref={this.$name}>{this.state.name}</span>
</h4>
);
}
}
PatientName.propTypes = {
name: PropTypes.string,
surname: PropTypes.string,
};
export default PatientName;
这工作正常(我现在不担心截断性能)...直到在父组件中选择另一位患者。然后,患者姓名不会更改,它仍然显示我通过道具传递的先前姓名。
我知道问题是从props派生状态,并且构造函数仅被调用一次,状态永远不会在之后刷新,等等,但是……这样做的正确“反应方式”是什么?
我来自Angular背景,我仍在努力解决这个问题。
谢谢!
PS:我正在使用React 16.6
答案 0 :(得分:0)
如果道具发生变化,您需要更新状态:
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();
}
}
首先if
更新状态并使用新的未截断的props
重新呈现并获得新的度量。第二个if
用于检查新的度量并在需要时截断。
答案 1 :(得分:0)
从React 16.3+开始,有一个新的组件生命周期,这是一个称为getDerivedStateFromProps的静态方法,它返回状态并在组件接收道具时被触发
因此在您的示例中,您可以像这样使用它:
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}`,
});
}