首页 > 解决方案 > 如何通过反应调用父事件的子方法?

问题描述

我有一个子组件需要听其中一个的 parent event。更准确地说,我在子组件中有一个函数,该函数event将父组件作为参数。我想在每次event发生时调用这个函数。

例如,下面是一个代码片段:

class Parent extends React.Component {
   handleKeyDown = (event) => {
      // Call the child function doSomething()
   }

   render() {
      return (
         <input
            type="text"
            onKeyDown={this.handleKeyDown}
         >

         <Child />
      )
   }
}
class Child extends React.Component {
   doSomething = (event) => {
      // Get the event from parent
   }

   render() {
      return (
         ...
      )
   }
}

我考虑了两种方法:

然而,这些解决方案似乎都不是很吸引人。我也考虑过使用 redux 函数,但我需要来自子组件和event父组件的数据......我想知道是否有一种干净的方法可以做到这一点?

标签: reactjsreact-redux

解决方案


更新:

我更新了我的组件以使用钩子并最终使用useRef()useImperativeHandle()forwardRef()来处理这种情况:

const Parent = () => {
   const childRef = useRef();

   const handleKeyDown = (event) => {
      // Call the child function doSomething()
      childRef.current.doSomething(event);
   };
   
   return (
      <input
         type="text"
         onKeyDown={handleKeyDown}
      >
    
      <Child ref={childRef} />
   );
};
const Child = forwardRef((props, ref) => {
   useImperativeHandle(ref, () => ({
      doSomething: (event) => {
         // Get the event from parent
      }
   }));

   return (
      [...]
   );
});


我决定在这篇文章1中使用Francis Malloch提供的解决方案:

class Parent extends React.Component {
   childCallables = null;
    
   setChildCallables = (callables) => {
      this.childCallables = callables;
   }
    
   handleKeyDown = (event) => {
      // Call the child function doSomething()
      this.childCallables.doSomething(event);
   }
    
   render() {
      return (
         <input
            type="text"
            onKeyDown={this.handleKeyDown}
         >
    
         <Child setCallables={this.setChildCallables} />
      )
   }
}
class Child extends React.Component {
   componentDidMount() {
      this.props.setCallables({
         doSomething: this.doSomething
      });
   }
    
   doSomething = (event) => {
      // Get the event from parent
   }
    
   render() {
      return (
         [...]
      )
   }
}

基本上,我使用道具来存储我需要从父级访问的子级方法。方法在子组件安装后保存在道具中。


1. 由于这是对一个完全不同的问题的答案,我认为将其标记为重复是没有意义的。


推荐阅读