MST

星途 面试题库

面试题:React Portal技术与组件上下文及事件冒泡处理

假设在使用React Portal将组件渲染到DOM其他位置后,如何确保组件能正确获取原组件树中的上下文(context)信息?同时,当在Portal渲染的组件内触发事件时,怎样处理事件冒泡,使其能像在原组件树内一样正常工作?
22.1万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

确保组件获取原组件树中的上下文(context)信息

  1. 使用React.createContext
    • 首先创建上下文对象,例如:
    import React from'react';
    const MyContext = React.createContext();
    
    • 在原组件树的上层组件中,通过 MyContext.Provider 提供上下文数据:
    <MyContext.Provider value={/* 上下文数据 */}>
      {/* 原组件树 */}
      <ComponentThatMayUsePortal />
    </MyContext.Provider>
    
    • 在使用 React Portal 渲染的组件中,通过 MyContext.ConsumeruseContext 钩子来获取上下文数据。
    • 使用 MyContext.Consumer
    import React from'react';
    import { MyContext } from './MyContext';
    const PortalComponent = () => {
      return (
        <MyContext.Consumer>
          {context => (
            {/* 使用上下文数据 */}
            <div>{context.someData}</div>
          )}
        </MyContext.Consumer>
      );
    };
    export default PortalComponent;
    
    • 使用 useContext 钩子(适用于函数式组件):
    import React, { useContext } from'react';
    import { MyContext } from './MyContext';
    const PortalComponent = () => {
      const context = useContext(MyContext);
      return (
        <div>{context.someData}</div>
      );
    };
    export default PortalComponent;
    
  2. 传递props
    • 也可以通过在原组件树向使用 Portal 的组件传递props的方式,将上下文相关的数据传递下去。例如:
    const ParentComponent = () => {
      const someData = { /* 上下文相关数据 */ };
      return (
        <ComponentThatMayUsePortal contextData={someData} />
      );
    };
    const ComponentThatMayUsePortal = ({ contextData }) => {
      // 在Portal组件中使用contextData
      return (
        //...
      );
    };
    

处理事件冒泡使其像在原组件树内一样正常工作

  1. 事件委托
    • 在原组件树中,事件冒泡是由浏览器的事件机制处理的。当使用 React Portal 将组件渲染到其他位置时,可以通过事件委托来模拟事件冒泡。
    • 在Portal渲染的组件内,给需要冒泡事件的元素添加事件监听器,例如:
    const PortalComponent = () => {
      const handleClick = (e) => {
        // 手动触发父组件中的事件处理函数
        const parentElement = document.getElementById('parent - component - id');
        if (parentElement) {
          const newEvent = new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            view: window
          });
          parentElement.dispatchEvent(newEvent);
        }
      };
      return (
        <div onClick={handleClick}>Click me</div>
      );
    };
    
  2. 使用React事件系统
    • React有自己的合成事件系统,它模拟了原生事件的行为。如果希望利用React的事件系统来处理事件冒泡,可以在原组件树的父组件中添加事件处理函数,然后通过props传递给Portal渲染的组件。
    • 例如:
    const ParentComponent = () => {
      const handleClick = () => {
        // 处理事件
      };
      return (
        <ComponentThatMayUsePortal onCustomClick={handleClick} />
      );
    };
    const ComponentThatMayUsePortal = ({ onCustomClick }) => {
      return (
        <div onClick={onCustomClick}>Click me</div>
      );
    };