如何创建反向反应门户

时间:2019-08-23 07:35:14

标签: javascript reactjs performance dom

React portals使您可以将React子元素渲染到页面上完全独立的其他DOM元素中。

我想做相反的事情:我想在页面的其他位置渲染一次DOM元素,然后根据我的反应树将其拉到我的React DOM输出中。

具体用法为Monaco Editor。它是一个复杂的组件,从头开始渲染很昂贵,但是更新却很便宜。在我的应用程序中,当用户打开/关闭不同的内容时,编辑器会出现/消失。这意味着每次打开新内容时,React都会从头开始创建组件,并且创建新编辑器的延迟使该动作比我想要的要慢。

我想渲染一次,将其隐藏在某个地方,然后在需要的位置将其显示在DOM中的正确位置。我知道我随时都只需要一个实例。

1 个答案:

答案 0 :(得分:0)

最后,我建立了一个自己动手做的库:https://github.com/httptoolkit/react-reverse-portal

一次将您的内容呈现一次,然后将其传递并插入到其他位置的DOM中,而无需重新呈现。

示例:

import * as portals from 'react-reverse-portal';

const MyComponent = (props) => {
    const portalNode = React.useMemo(() => portals.createPortalNode());

    return <div>
        <portals.InPortal node={portalNode}>
            <MyExpensiveComponent
                myProp={"defaultValue"}
            />
        </portals.InPortal>

        { props.componentToShow === 'component-a'
            ? <ComponentA portalNode={portalNode} />
            : <ComponentB portalNode={portalNode} /> }
    </div>;
}

const ComponentA = (props) => {
    return <div>
        A:
        <portals.OutPortal node={props.portalNode} />
    </div>;
}

const ComponentB = (props) => {
    return <div>
        B:
        <portals.OutPortal
            node={props.portalNode}
            myProp={"newValue"}
            myOtherProp={123}
        />
    </div>;
}