简体   繁体   English

如何创建反向反应门户

[英]How to create a reverse react portal

React portals let you render a React child into a different DOM element, somewhere totally separate on the page. React门户使您可以将React子元素呈现到页面上完全独立的其他DOM元素中。

I want to do the reverse: I want to render a DOM element once, elsewhere on the page, and then pull it into my React DOM output depending on my react tree. 我想做相反的事情:我想在页面的其他位置渲染一次DOM元素,然后根据我的react树将其拉到我的React DOM输出中。

The specific use case for this is Monaco Editor . 特定的用例是Monaco Editor It's a complex component, which is expensive to render from scratch, but cheap to update. 它是一个复杂的组件,从头开始渲染很昂贵,但是更新却很便宜。 In my application, the editor appears/disappears as users open/close different content. 在我的应用程序中,当用户打开/关闭不同的内容时,编辑器会出现/消失。 That means React creates the component from scratch each time new content is opened, and the delay to create a new editor makes that action a slower than I'd like. 这意味着每次打开新内容时,React都会从头开始创建组件,并且创建新编辑器的延迟使该动作比我想要的要慢。

I'd like to render it once, hide it somewhere, and then show it in the right place in my DOM when & where it's needed. 我想渲染一次,将其隐藏在某个地方,然后在需要的位置将其显示在DOM中的正确位置。 I know that I only need one instance at any time. 我知道我随时都只需要一个实例。

In the end I built a library to do it myself: https://github.com/httptoolkit/react-reverse-portal . 最后,我建立了一个自己做的库: https : //github.com/httptoolkit/react-reverse-portal

Render your content in one place, once, and pass it around and insert it into the DOM somewhere else without rerendering. 一次将您的内容渲染一次,然后将其传递并插入到其他位置的DOM中,而无需重新渲染。

Example: 例:

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>;
}

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

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