首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在react-dom createPortal中使用react-tether,以便能够根据绑定到的组件设置绑定组件的样式?

如何在react-dom createPortal中使用react-tether,以便能够根据绑定到的组件设置绑定组件的样式?
EN

Stack Overflow用户
提问于 2019-01-04 00:12:19
回答 1查看 526关注 0票数 1

我有一个组件,我在其中呈现一些按钮。每个按钮都应该有它的工具提示。我想让工具提示在我:悬停按钮时出现。但是因为我的工具提示不能只包含文本,所以我不能使用气球之类的东西,也不能只用css创建它。

我的想法是使用react-tether将我自己的工具提示组件绑定到按钮上。但是,如果我将鼠标悬停在按钮上,工具提示就会出现。因此,我希望使用react-portal在按钮组件中移动工具提示,以便能够根据其实际的父级设置工具提示的样式。

这是我已经想到的想法,但它并不是这样工作的。

代码语言:javascript
复制
    export const Bar: React.StatelessComponent<IBarProps> = (props) => {
    const { button1, button2} = props;

      return (
        <div>
          <TetherComponent
          ...
          >
            <Button
             ref={button1ref} //???
             ...(some props)
            >
              {button1.text}
            </Button>
            {
              createPortal(
                  <tooltip>button1.tooltipText</tooltip>,
                  button1ref)
            }
          </TetherComponent>

          <TetherComponent
          ...
          >...the same with second button
          </TetherComponent>
        </div>
    )}

其中Tooltip是React.StatelessComponent,而Button是简单的React.PureComponent。

我通常会遇到这样的问题,按钮是JSX.Element而不是元素,所以我不能将其用作门户中的目标元素。另一件事是,我不确定在这种情况下如何使用ref,以及使用id是否更好。我对任何想法都持开放态度。

EN

回答 1

Stack Overflow用户

发布于 2019-01-04 02:18:37

我认为我写的这段平静的代码会对你有所帮助。它的工作原理与工具提示不完全相同,但它向您展示了如何使用portal。

代码语言:javascript
复制
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from "prop-types";

class TooltipButton extends Component {
    state = {
        isHovered: false
    };

    buttonRef = React.createRef();

    onMouseOver = isOver => {
        this.setState({
            isHovered: isOver
        });
    };

    render() {
        const tooltip = (
            <div>
                {this.props.tooltip}
            </div>
        );

        return (
            <div>
                <button
                    ref={this.buttonRef}
                    onMouseEnter={() => this.onMouseOver(true)}
                    onMouseLeave={() => this.onMouseOver(false)}
                >
                    {this.props.text}
                </button>
                {this.state.isHovered ?
                    ReactDOM.createPortal(tooltip, this.buttonRef.current) :
                    undefined}
            </div>
        );
    }
}

TooltipButton.propTypes = {
    text: PropTypes.string.isRequired,
    tooltip: PropTypes.string.isRequired
};

export default TooltipButton;

此示例显示了如何使用门户,但门户的目的是将某些内容(工具提示元素)添加到另一个元素(例如document.body)中,而不是添加到同一元素中。在这种情况下,createPortal实际上没有做任何事情。

打开同一个房间的门户没有任何意义:)

我认为你需要这样做:

代码语言:javascript
复制
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from "prop-types";

class TooltipButton extends Component {
    state = {
        isHovered: false
    };

    buttonRef = React.createRef();

    constructor() {
        super();
        this.tooltipElement = document.createElement('div');
    }

    onMouseOver = isOver => {
        this.setState({
            isHovered: isOver
        });
    };

    componentDidMount() {
        document.body.appendChild(this.tooltipElement);
    }

    componentWillUnmount() {
        document.body.removeChild(this.el);
    }

    render() {
        let buttonRect;
        let tooltip;
        if (this.buttonRef.current) {
            buttonRect = this.buttonRef.current.getBoundingClientRect();
            tooltip = (
                <div style={{
                    zIndex: Number.MAX_SAFE_INTEGER,
                    position: 'absolute',
                    top: buttonRect.top,
                    left: buttonRect.right,
                    backgroundColor: 'lightgrey'
                }}>
                    {this.props.tooltip}
                </div>
            );
        }

        return (
            <div>
                <button
                    ref={this.buttonRef}
                    onMouseEnter={() => this.onMouseOver(true)}
                    onMouseLeave={() => this.onMouseOver(false)}
                >
                    {this.props.text}
                </button>
                {this.state.isHovered ?
                    ReactDOM.createPortal(tooltip, this.tooltipElement) :
                    undefined}
            </div>
        );
    }
}

TooltipButton.propTypes = {
    text: PropTypes.string.isRequired,
    tooltip: PropTypes.string.isRequired
};

export default TooltipButton;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54025981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档