繁体   English   中英

Append 点击时反应组件

[英]Append react component on click

我正在尝试编写一个在单击元素时出现的工具提示组件。 我见过这种组件的实现,其中工具提示有点包裹在另一个元素上,但这不适合我。 我在想也许因为我可以访问 event.target 我只是 select 目标的父级,然后创建一个工具提示组件的新实例,其绝对定位是从目标的 position 和 Z9516DFB15F51C7EE19A4D46B8C0 计算得出的,但我得到一个错误我的 Tooltip 的新实例不是节点类型,因此它不是有效的子节点。 TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

Tooltip 是一个 class 组件,它只返回一个带有一些文本的<div>

class Tooltip extends React.Component {
    constructor(props) {
        super(props);
    }

    basicStyle = {
        width: 80,
        height: 30,
        backgroundColor: '#333333',
        position: 'absolute',
        left: this.props.tooltipLeft,
        right: this.props.tooltipTop,
    };

    render() {
        return <div style={this.basicStyle}>tooltip</div>;
    }
}

这是此演示应用程序的代码:

import React from 'react';
import Tooltip from './Tooltip';
import './App.css';

function App() {
    const clickHandler = (event) => {
        //get coordinates to position a Tooltip
        const pos = event.target.getBoundingClientRect();
        const tooltipLeft = pos.left + pos.width / 2;
        const tooltipTop = pos.top - 20;

        const tooltip = new Tooltip(tooltipLeft, tooltipTop);

        const parent = event.target.parentNode;
        parent.appendChild(tooltip);
    };

    return (
        <div className='wrapper'>
            <div className='box one' onClick={clickHandler}></div>
            <div className='box two' onClick={clickHandler}></div>
            <div className='box three' onClick={clickHandler}></div>
        </div>
    );
}

export default App;

我也尝试通过使用门户对useRefReactDOM做同样的事情(不确定它是否是正确的使用方式),但它没有帮助,即使点击时不再显示错误消息,只是没有任何反应. 在这种情况下,我使用的代码如下:

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import Tooltip from './Tooltip';
import './App.css';

function App() {
    const parentRef = useRef(null);

    const clickHandler = (event) => {
        //get coordinates to position a Tooltip
        const pos = event.target.getBoundingClientRect();
        const tooltipLeft = pos.left + pos.width / 2;
        const tooltipTop = pos.top - 20;

        const tooltip = new Tooltip(tooltipLeft, tooltipTop);
        ReactDOM.createPortal(tooltip, parentRef.current);
    };

    return (
        <div className='wrapper' ref={parentRef}>
            <div className='box one' onClick={clickHandler}></div>
            <div className='box two' onClick={clickHandler}></div>
            <div className='box three' onClick={clickHandler}></div>
        </div>
    );
}

export default App;

我觉得我在这里遗漏了一些明显的东西,但我无法得到它。 有人可以向我解释我在两次尝试中做错了什么吗?

更新:我意识到我应该多说一点:对我想要实现的目标进行一点解释。 基本上,我正在构建一个能够自定义其上的每个元素的站点,这就是该工具提示组件的作用。 我在这里没有使用条件渲染,因为这需要我手动将钩子/条件添加到可以调用工具提示的每个可能的位置,或者仅使用具有不同位置和内容的一个实例。 我需要能够为大量元素显示多个工具提示,并且它们应该能够同时打开,这就是我使用 class 组件和 appendChild() 的原因。

您应该使用 clickhandler 更新您的 state,然后根据 state 有条件地绘制工具提示。 我承认我以前没有使用过门户,所以我不确定,但“状态”方式非常简单。

基本上是这样的:

const [pos,updatePos] = useState(null)

const clickHandler = (event) => {
    updatePos(event.target.getBoundingClientRect())
}

return (
        <div className='wrapper' ref={parentRef}>
            <div className='box one' onClick={clickHandler}></div>
            <div className='box two' onClick={clickHandler}></div>
            <div className='box three' onClick={clickHandler}></div>
            { pos && (<ToolTip position={pos}/>) }
        </div>
    );

所以看起来你不能只是使用appendChild()来整理 append 反应组件,因为appendChild()是本机 javascript ZC1C425268E68385D1AB5074C17A7A94F14Z 组件的情况下是 render() 的方法组件(仅在类的情况下)和返回值object 而不是任何方式的节点(因为 react 为您管理 DOM)。 但是我不知道为什么门户网站不起作用,因为我对它们了解不多。

如果有人感兴趣,我还设法编写了一个控制工具提示的自定义钩子/组件。 我最终使用 useState 挂钩来存储数组所有活动的工具提示和调用这些工具提示的元素数组。 这只是一个原始原型,但它正在工作。 稍后我会添加一些功能并完善它,但现在它只是一个工具提示虚拟对象。

https://codepen.io/ClydeTheCloud/pen/MWKJQza

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM