【问题标题】:Can two React distinct and mounted components communicate with each other using props?两个 React 不同且已安装的组件可以使用 props 相互通信吗?
【发布时间】:2020-09-01 10:49:02
【问题描述】:

一个简单的例子来解释我的问题:

  • ButtonComponent 是安装在 <div id="btn-container"> 元素上的组件
  • ModalComponent 是安装在 <div id="modal-container"> 元素上的组件

因此两个组件安装在页面中不同位置的不同元素上,不共享一个公共 React 元素。

ModalComponent 接收名为isOpen 的道具以触发其可见性:

<ModalComponent isOpened={isOpened} />

ButtonComponent 应该以某种方式将属性isOpen 传递给ModalComponent,而不共享相同的“根”组件。这甚至可能吗?

当然,执行此操作的“正常方式”是ButtonPlusModalComponent,如下所示:

export const ButtonPlusModalComponent = () => {
    const [isOpened, setIsOpened] = useState(false);
        
    return (
      <>
        <ButtonComponent onClick={() => setIsOpened(true)} />
        <ModalComponent isOpened={isOpened} />
      </>
    );
};

我将 React 与常规 PHP 应用程序一起使用,所以...不是一个完整的“完整”React 应用程序,只有页面的某些部分是 React 组件,根本没有路由器。 所以,我在页面的某处有那个按钮。该按钮应该打开模态组件,这是一个...放置在页面其他位置的 React 组件。

编辑:解释问题的原因。

【问题讨论】:

  • 如果您的应用使用 Redux,您是否尝试过?否则,您可以为此使用 RxJs Observable
  • 主要问题是如何将道具传递给两个组件?我认为您描述了XY problem,请尝试用示例解释您要做什么。即使你可以在没有共同父母的情况下交流,你想如何传递这些道具?
  • @DennisVash 我在更新的问题中解释了原因。
  • 上下文或redux
  • @LuisMendes535 我不认为我可以使用上下文,因为(请参阅我的编辑)我在页面中呈现了一些反应组件,但不是“单个”反应应用程序。那么你会把上下文提供者放在哪里呢?

标签: reactjs


【解决方案1】:

你必须两个组件共享一个共同的父级,这就是 React 的工作原理Data Flows Down

如果可以,将它们耦合到同一棵树中并使用常见的解决方案,例如Context API

但是,您描述的是组件解耦的情况,因此为了有一个共同的父级将一个组件安装到另一个 HTML 元素中,您需要使用React.Portal

因此,您需要一个组件来使用门户安装另一个组件:

<body>
  <div id="modal-container"></div>
  <div id="btn-container"></div>
</body>
const Modal = ({ open }) => open && <>Modal</>;

const App = () => {
  const [open, toggleOpen] = useReducer((p) => !p, true);
  return (
    <>
      <button onClick={toggleOpen}>toggle</button>
      {ReactDOM.createPortal(
        <Modal open={open} />,
        document.getElementById("btn-container")
      )}
    </>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("modal-container")
);

【讨论】:

  • 所以我认为这是我一直在寻找的,门户 :) 对我来说很清楚。同一个门户(容器)可以呈现超过 1 个组件吗? IE。如果多次调用 ReactDOM.createPortal 是全部渲染还是最后一个获胜?
  • 它们只是堆叠,你可以在沙箱中查看。
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 2018-08-10
  • 2014-06-26
相关资源
最近更新 更多