懒孩子装

时间:2018-02-13 23:06:24

标签: reactjs

我对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;

0 个答案:

没有答案
相关问题