1. 程式人生 > >react16 ref 自適應寬高

react16 ref 自適應寬高

class Card extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      width: props.width || -1,
      height: props.height || -1,
    }
  }

  componentDidMount() {
    this.updateSize();
    window.addEventListener('resize', () => this.updateSize());
  }

  componentWillUnmount() {
    window.removeEventListener('resize', () => this.updateSize());
  }

  updateSize() {
    try {
      const parentDom = ReactDOM.findDOMNode(this).parentNode;
      let { width, height } = this.props;
      //如果props沒有指定height和width就自適應
      if (!width) {
        width = parentDom.offsetWidth;
      }
      if (!height) {
        height = width * 0.38;
      }
      this.setState({ width, height });
    } catch (ignore) {
    }
  }

  render() {
    return (
      <div className="test" style={ { width: this.state.width, height: this.state.height } }>
        {`${this.state.width} x ${this.state.height}`}
      </div>
    );
  }
}

ReactDOM.render(
  <Card/>,
  document.getElementById('root')
);
import React from 'react';
import PropTypes from 'prop-types';
import { ModalProps } from './types';
// import styles from './index.less';
// import ReactDOM from 'react-dom';

import { Modal as AntdModal } from 'antd';

export interface IState {
    scroll: React.CSSProperties,
    width: number | undefined,
    height: number | undefined
}

class Modal extends React.PureComponent<ModalProps, IState> {
    constructor(props) {
        super(props);
        this.state = {
            scroll: {},
            width: props.width || -1,
            height: props.height || -1,
        }
        this.refParentDom = React.createRef();
        this.refChildDom = React.createRef();

    }
    private refParentDom: React.RefObject<HTMLDivElement>;
    private refChildDom: React.RefObject<HTMLDivElement>;


    static propsTypes = {
        visible: PropTypes.bool,
    }
    static defaultProps = {
        centered: true
    }
    private handleOk = (e: React.MouseEvent<HTMLButtonElement>) => {
        if (this.props.ok) this.props.ok(false, e);
    }

    private handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
        if (this.props.cancel) this.props.cancel(false, e);
    }
    componentDidMount() {
        this.updateSize();
        window.addEventListener('resize', () => this.updateSize());
    }
    componentWillUnmount() {
        window.removeEventListener('resize', () => this.updateSize());
    }
    updateSize() {
        //監聽螢幕高度
        //獲取content 高度 如果大於螢幕高度 90% 則加滾動條
        try {
            const refParentDom = this.refParentDom.current;
            const refChildDom = this.refChildDom.current;
            const clientHeight = document.body.clientHeight;
            let { height } = this.props;
            if (!height) {
                height = clientHeight * 0.9 - 110;
                if (refChildDom && refChildDom.offsetHeight < height) {
                    console.log(refChildDom.offsetHeight, "refChildDom")
                    height = refChildDom.offsetHeight;
                }
            }
            console.log(height, "height");
            if (refParentDom) {
                console.log(refParentDom.offsetHeight, "refParentDom")
            }
            console.log(clientHeight, "clientHeight")
            this.setState({ height });
        } catch (ignore) {

        }
    }
    render() {
        //centered 預設垂直居中
        const {
            visible,
            // children,
            centered,
            ...resProps
        } = this.props;
        return (
            <AntdModal
                visible={visible}
                onOk={this.handleOk}
                onCancel={this.handleCancel}
                centered={centered}
                {...resProps}
                style={{ paddingBottom: 'inherit' }}
            >
                <div ref={this.refParentDom} style={{
                    width: this.state.width,
                    height: this.state.height,
                    overflow: 'scroll'
                }}>
                    <div style={{ height: '500px' }} ref={this.refChildDom}>content</div>
                </div>
            </AntdModal>
        )
    }
}

export default Modal;