如何将React组件相对于其父元素定位?

34

我有一个包含一个子 React 组件的父 React 组件。

<div>
  <div>Child</div>
</div>
我需要为子组件应用样式,以在其父组件内定位,但它的位置取决于父组件的大小。
render() {
  const styles = {
    position: 'absolute',
    top: top(),    // computed based on child and parent's height
    left: left()   // computed based on child and parent's width
  };
  return <div style={styles}>Child</div>;
}

因为子元素和父元素的宽度和高度是功能函数,所以我无法在此处使用百分比值。

React 的实现方式是什么?


@Seth,你能澄清一下“因为顶部和左侧位置是子元素和父元素的宽度和高度的函数”这句话吗?你到底想要实现什么? - Shoe Diamente
4个回答

22

解决这个问题的方法是按照Refs to Components中描述的使用ref。

潜在的问题在于需要正确定位元素的DOM节点(以及其父DOM节点),但在第一次渲染之前不可用。来自上面链接文章中的引用:

几乎所有执行DOM测量的操作都需要访问“本地”组件并使用ref访问其底层DOM节点。Refs是实现这一点的唯一实用方式之一。

以下是解决方案:

getInitialState() {
  return {
    styles: {
      top: 0,
      left: 0
    }
  };
},

componentDidMount() {
  this.setState({
    styles: {
      // Note: computeTopWith and computeLeftWith are placeholders. You
      // need to provide their implementation.
      top: computeTopWith(this.refs.child),
      left: computeLeftWith(this.refs.child)
    }
  })
},

render() {
  return <div ref="child" style={this.state.styles}>Child</div>;
}

这将在第一次渲染后正确地定位元素。如果您还需要在属性更改后重新定位元素,则在componentWillReceiveProps(nextProps)中进行状态更改。


1
computeTopWithcomputeLeftWith是React函数吗?我需要导入它们吗? - Simon Hessner
1
@SimonH,“compute...”函数只是占位符;您需要提供逻辑。 - Seth
6
@Seth - 你应该在评论中说明它们是“占位符”,这会产生误导。 - vsync
你能完成答案吗? - Oliver Dixon

5

这是我的做法

const parentRef = useRef(null)

const handleMouseOver = e => {
    const parent = parentRef.current.getBoundingClientRect()
    const rect = e.target.getBoundingClientRect()

    const width = rect.width
    const position = rect.left - parent.left

    console.log(`width: ${width}, position: ${position}`)
}

<div ref={parentRef}>
    {[...Array(4)].map((_, i) => <a key={i} onMouseOver={handleMouseOver}>{`Item #${i + 1}`}</a>)}
</div>

0
要将一个React组件相对于其父组件定位,你可以使用CSS并指定定位属性。
以下是一个示例:
import React from 'react'; import './Component.css';
const Component = () => {
  return (
    <div className="parent">
      <div className="child">Hello, World!</div>
    </div>
  );
};

export default Component;

创建一个名为Component.css的CSS文件,并添加以下样式:
.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

在这段CSS代码中,我们将父组件的位置设置为相对定位。这将确立父组件作为其子元素的定位上下文。
对于子组件,我们将其位置设置为绝对定位。这将使其脱离正常的文档流,并相对于最近的已定位祖先(在这种情况下是父组件)进行定位。 top: 50%left: 50%属性将子组件水平和垂直居中于其父组件内。 transform: translate(-50%, -50%)属性确保子组件通过将其自身宽度和高度的50%向相反方向移动来精确居中。
通过这些CSS样式,子组件将被定位在其父组件的中心。您可以根据需要调整定位值(如top、left和transform)以实现所需的位置。

-3

做这件事的正确方法是使用CSS。如果您将position:relative应用于父元素,则可以使用topleft相对于该父元素移动子元素。您甚至可以使用百分比,例如top:50%,它利用了父元素的高度。


我不能使用百分号;我更新了问题以澄清这一点。 - Seth
1
@Seth 你试过将 position: relative 应用于父元素吗? - Brett
1
即使相对于父元素,当您有多个嵌套元素级别的情况下,父元素的高度可能会有所不同。 - backdesk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接