javascript - 基于 getBoundingClientRect() 问题进行样式注入(inject)的 React.cloneElement

标签 javascript reactjs

我正在尝试获取一个布局,其中容器组件决定子组件的 style ,或更具体地说是子组件 style 属性的 width 属性。

TL;DR:如何根据父级的 getBoundingClientRect() 为所有渲染(包括初始渲染)设置子级 props。

我能够在组件安装后计算所需的宽度,在容器组件上使用 getBoundingClientRect() ,然后通过我的计算运行它,但对于初始渲染,这会导致成为不存在的值,因为显然它仍然不在 DOM 中。

示例如下:

class Container extends Component {
    constructor(props) {
        super(props);
        this.containerRef = React.createRef();
        this.containerWidth = null;
        this.columnWidth= null;
    }

    componentDidMount() {
        this.containerWidth = this.containerRef.current.getBoundingClientRect().width;
        this.columnWidth = this.containerBaseWidth / this.props.columns;
    }

    injectChildrenWidth = () => {
        return React.Children.toArray(this.props.children)
            .map(el => {
                return React.cloneElement(
                    el,
                    { componentWidth: this.columnWidth }
                );
            });
    };

    render() {
        const Columns = this.injectChildrenWidth();
        return (
            <div ref={this.containerRef} >
                {Columns}
            </div>
        );
    }
}

允许父组件根据其自己的 getBoundingClientRect() 宽度“决定”子组件属性的宽度的正确方法是什么?初始渲染永远不会有父级的值,因为它不在 DOM 中,并且我需要获取该值才能渲染子级,因此我需要 render() 方法中的值。

我很确定整个概念是错误的,我应该考虑一些不同的生命周期方法或东西,只是不知道在哪里/什么。

最佳答案

使用状态

class Container extends Component {
  constructor(props) {
    super(props);
    this.containerRef = React.createRef();
    this.state = {
      containerWidth: undefined,
      columnWidth: undefined
    };
  }

  componentDidMount = () => {
    let containerWidth = this.containerRef.current.getBoundingClientRect().width;
    let columnWidth = containerWidth / this.props.children.length;
    this.setState({ containerWidth, columnWidth });
  };

  injectChildrenWidth = () => {
    return React.Children.toArray(this.props.children).map(el => {
      return React.cloneElement(el, { componentWidth: this.state.columnWidth });
    });
  };

  render() {
    const Columns = this.injectChildrenWidth();
    return <div ref={this.containerRef}>{Columns}</div>;
  }
}

关于javascript - 基于 getBoundingClientRect() 问题进行样式注入(inject)的 React.cloneElement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56492397/

相关文章:

javascript - react : Search Results not being displayed?

JavaScript 命名空间对象字面量

javascript:检查对象是否具有特定元素或属性的最佳方法?

reactjs - 使用 Webpack 进行 react : PropTypes appearing in final bundle

reactjs - 具有 React 上下文的当前用户

Django、React、Redux : Serving up images

javascript - React 组件在 RequireJS+Jasmine 单元测试中不起作用

javascript - 仅在指定字符的第一个实例上拆分字符串

javascript - 使用 lodash 或 javascript 从对象数组中删除基本键对象

html - 如何使用 Typescript 在 React 中定义 <video> 引用的类型?