javascript 如何使用转换创建一个React Modal(附加到`<body>`)?





4 Answers

我编写了应该帮助你的模块react-portal

javascript reactjs modal-dialog css-transitions

这个答案中有一个模态https://.com/a/26789089/883571 ,它通过将其附加到<body>来创建基于React的模态。 但是,我发现它与React提供的转换插件不兼容。

如何创建一个有过渡(在进入和离开期间)?




正如其他答案所述,这可以使用门户网站完成。 从v16.0开始, Portals包含在React中。

<body>
  <div id="root"></div>
  <div id="portal"></div>
</body>

通常,当您从组件的render方法返回一个元素时,它会作为最近父节点的子节点挂载到DOM中,但是通过门户,您可以将子节点插入DOM中的其他位置。

const PortalComponent = ({ children, onClose }) => {
  return createPortal(
    <div className="modal" style={modalStyle} onClick={onClose}>
      {children}
    </div>,
    // get outer DOM element
    document.getElementById("portal")
  );
};

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

    this.state = {
      modalOpen: false
    };
  }

  render() {
    return (
      <div style={styles}>
        <Hello name="CodeSandbox" />
        <h2>Start editing to see some magic happen {"\u2728"}</h2>
        <button onClick={() => this.setState({ modalOpen: true })}>
          Open modal
        </button>
        {this.state.modalOpen && (
          <PortalComponent onClose={() => this.setState({ modalOpen: false })}>
            <h1>This is modal content</h1>
          </PortalComponent>
        )}
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

here查看工作示例。




我写了一个图书馆来帮助解决这个问题。 我避免使用Portal策略所使用的DOM插入黑客,而是使用基于上下文的注册表将组件从源传递到目标。

我的实现使用标准的React渲染周期。 传送/注入/传输的组件不会在目标上产生双重渲染周期 - 一切都是同步发生的。

API的结构也可以阻止在代码中使用魔术字符串来定义源/目标。 相反,您需要显式创建和装饰将用作目标(Injectable)和源(Injector)的组件。 由于这类事情通常被认为是非常神奇的,我认为显式的组件表示(需要直接导入和使用)可能有助于缓解组件注入位置的混淆。

虽然我的库不允许您呈现为document.body的直接子项,但您可以通过绑定到组件树中的根级组件来实现可接受的模式效果。 我计划很快添加一个这个用例的例子。

有关详细信息,请参阅https://github.com/ctrlplusb/react-injectables




我认为这段代码或多或少是自我解释的,涵盖了大多数人都在寻找的核心解决方案:

ReactDOM.render(
  <Modal />,
  document.body.appendChild( document.createElement( 'div' ) ),
)



Related