react16 ref 自适应宽高

本文介绍了一个使用React实现的自适应组件,该组件能够根据父元素的大小调整自身的宽度和高度,同时提供了一个模态框组件,其高度自适应为屏幕的90%,并在内容超过该高度时自动添加滚动条。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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')
);
/*
 * @Author: songxue
 * @Date: 2018-12-18 13:54:44
 * @Last Modified by: yehq
 * @Last Modified time: 2018-12-19 13:51:23
 * @Module Name: modal 框  自适应 最大高度是屏幕的90%
 */
import React from 'react';
import PropTypes from 'prop-types';
import { ModalProps } from './types';

import { Modal as AntdModal } from 'antd';

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

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.onOk) this.props.onOk(e);
    }

    private handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
        if (this.props.onCancel) this.props.onCancel(e);
    }
    componentDidMount() {
        this.updateSize();
        window.addEventListener('resize', this.updateSize);
    }
    componentWillUnmount() {
        window.removeEventListener('resize', this.updateSize);
    }
    componentWillReceiveProps({ visible }) {
        console.log(visible,"visible")
        if (visible) {
            this.updateSize();
        }
    }
    updateSize = () => {
        //监听屏幕高度
        //获取content 高度 如果大于屏幕高度 90% 则加滚动条
        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) {
                height = refChildDom.offsetHeight;
            }
        }
        this.setState({ height });
    }
    render() {
        //centered 默认垂直居中
        const {
            visible,
            children,
            centered,
            style,
            ...resProps
        } = this.props;
        const styleObj = this.state.scroll.overflow === 'scroll' ?
                {
                    width: this.state.width,
                    height: this.state.height,
                    ...this.state.scroll
                } :
                this.state.scroll;
        return (
            <AntdModal
                visible={visible}
                onOk={this.handleOk}
                onCancel={this.handleCancel}
                centered={centered}
                {...resProps}
                style={{ paddingBottom: 'inherit', ...style }}
            >
                <div
                    ref={this.refParentDom}
                    style={styleObj}
                >
                    <div ref={this.refChildDom}>
                        {children}
                    </div>
                </div>
            </AntdModal>
        )
    }
}

export default Modal;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值