pro-collection / interview-question

目标:收集全网经典面试问题
713 stars 53 forks source link

[React] 如何将一个层级非常深的子组件的某一个方法, 抛出给上层组件使用【热度: 465】 #1052

Open yanlele opened 3 weeks ago

yanlele commented 3 weeks ago

关键词:调用子组件方法

在 React 中,可以通过以下几种方式将一个层级非常深的子组件的某一个方法抛出给上层组件使用:

一、使用回调函数传递

  1. 在父组件中定义一个回调函数,并将其作为属性传递给子组件的父级组件,依次向下传递,直到目标子组件。

    例如:

    function ParentComponent() {
     const handleDeepMethod = () => {
       console.log("调用了深层子组件的方法");
     };
     return <ChildComponent onDeepMethod={handleDeepMethod} />;
    }
    
    function ChildComponent({ onDeepMethod }) {
     return <GrandChildComponent onDeepMethod={onDeepMethod} />;
    }
    
    function GrandChildComponent({ onDeepMethod }) {
     const deepMethod = () => {
       console.log("深层子组件的方法被执行");
       onDeepMethod();
     };
     return <button onClick={deepMethod}>触发深层方法</button>;
    }
  2. 在深层子组件中,当特定条件触发时,调用这个通过层层传递下来的回调函数,从而让父组件执行相应的操作。

二、使用 React 的 Context API

  1. 创建一个 Context:

    const DeepMethodContext = React.createContext();
  2. 在父组件中提供值:

    function ParentComponent() {
     const handleDeepMethod = () => {
       console.log("调用了深层子组件的方法");
     };
     return (
       <DeepMethodContext.Provider value={handleDeepMethod}>
         <ChildComponent />
       </DeepMethodContext.Provider>
     );
    }
  3. 在深层子组件中获取 Context 值并调用:

    function GrandChildComponent() {
     const handleDeepMethod = React.useContext(DeepMethodContext);
     const deepMethod = () => {
       console.log("深层子组件的方法被执行");
       handleDeepMethod();
     };
     return <button onClick={deepMethod}>触发深层方法</button>;
    }

三、使用 Custom Events 还有一种方法是使用自定义事件(Custom Events)。

  1. 在深层子组件中创建并派发自定义事件:

    function GrandChildComponent() {
     const deepMethod = () => {
       console.log("深层子组件的方法被执行");
       const event = new CustomEvent("deepMethodTriggered", { detail: {} });
       window.dispatchEvent(event);
     };
     return <button onClick={deepMethod}>触发深层方法</button>;
    }
  2. 在父组件中监听这个自定义事件:

    function ParentComponent() {
     const handleDeepMethod = () => {
       console.log("调用了深层子组件的方法");
     };
     useEffect(() => {
       window.addEventListener("deepMethodTriggered", handleDeepMethod);
       return () => {
         window.removeEventListener("deepMethodTriggered", handleDeepMethod);
       };
     }, []);
     return <ChildComponent />;
    }