我对React很陌生,所以我希望我的问题不会甩掉......
我开发了一个可折叠的ui组件,可以通过单击按钮将身体从打开切换到关闭。这很好,我只是对一件事感到好奇。
此组件可以包含大量数据/组件。可以考虑100个或更多可折叠组件的列表,每个组件可以有另外100个子组件。
所以我只想添加扩展/打开的组件的子代。
所以我想我要添加像#34; hasBeenOpened"默认为false。第一次打开时,hasBeenOpened将设置为true,加载子项并计算高度。
问题在于,无法计算高度,因为在发生开启点击时DOM尚未更新。
我怎么能解决这个问题?感谢您的支持!
(协作通过css过渡高度进行动画处理,因此我必须计算元素的高度,因为内容在高度上是动态的)
import React from "react";
import PropTypes from "prop-types";
import "./Collabsable.css";
import FontAwesomeIcon from '@fortawesome/react-fontawesome'
class Collabsable extends React.Component {
constructor(props) {
super(props);
if (props.open) {
this.state = {
isExpanded: true,
inTransition: false,
hasBeenOpened: true
};
} else {
this.state = {
isExpanded: false,
inTransition: false,
hasBeenOpened: false
};
}
}
handleClickToggle(event) {
this.setState({
isExpanded: !this.state.isExpanded,
height: this.refs.innerContainer.clientHeight,
hasBeenOpened: true
});
}
handleTransitionEnd(event) {
if (this.state.isExpanded) {
this.setState({ inTransition: false });
} else {
this.setState({ inTransition: true });
}
}
render() {
const {headerTitle, headerAdditionalButtons} = this.props;
const {isExpanded, height} = this.state;
const currentHeight = isExpanded ? height : 0;
let children = this.props.lazyChildrenRender &&
!this.state.hasBeenOpened &&
!this.state.isExpanded &&
!this.state.inTransition ? null : this.props.children;
return (
<div className={`collabsable ${isExpanded ? 'is-expanded': ''}`}>
<div className={"collabsable_header"}>
<div className="collabsable_header_title">{headerTitle}</div>
<div className="collabsable_header_buttons">
<div className="collabsable_header_buttons_additional">{headerAdditionalButtons}</div>
<div className="collabsable_header_buttons_toggle">
<button onClick={(event) => this.handleClickToggle(event)}><FontAwesomeIcon icon="angle-down" /></button>
</div>
</div>
</div>
<div className="collabsable_container" style={{height: currentHeight+'px'}} onTransitionEnd={(event) => this.handleTransitionEnd(event)}>
<div className="collabsable_container_inner" ref="innerContainer">
{children}
</div>
</div>
</div>
)
}
}
Collabsable.propTypes = {
headerTitle: PropTypes.string.isRequired,
headerAdditionalButtons: PropTypes.object,
lazyChildrenRender: PropTypes.bool,
hasBeenOpened: PropTypes.bool,
open: PropTypes.bool
};
Collabsable.defaultProps = {
headerTitle: "Collabsable Component Headline",
headerAdditionalButtons: null,
lazyChildrenRender: false,
hasBeenOpened: false,
open: false
};
export default Collabsable;