我是个新手,大约一周前才开始使用它。我试图在一个组件中开发一个截断的文本功能,但却陷入了一个常见的新手陷阱。
我有一个患者信息组件,它显示了人们的个人数据,如姓名、生日等。该组件在视觉上设计为固定宽度的卡片,当宽度超过卡片的宽度时,需要截断人名:
(“截断”格式是非常具体的,我不能只使用CSS )
我通过props将人名和姓氏从父组件传递给子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传递的之前的名字。
我知道问题是从属性派生状态,构造函数只被调用一次,之后状态永远不会刷新,等等,但是...这样做的正确“反应方式”是什么?
我来自一个棱角分明的背景,我仍在努力理解这一点。
谢谢!
PS:我正在使用React 16.6
发布于 2019-03-22 17:27:31
如果道具改变,你需要更新你的状态:
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
用于检查新的测量值,并在需要时进行截断。
发布于 2019-03-22 18:57:43
自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}`,
});
}
https://stackoverflow.com/questions/55296335
复制相似问题