ReactJS V16如何将父函数传递给孙事件处理程序[重复]

Posted

技术标签:

【中文标题】ReactJS V16如何将父函数传递给孙事件处理程序[重复]【英文标题】:ReactJS V16 How to pass parent function to grandchild event handler [duplicate] 【发布时间】:2018-09-26 10:23:15 【问题描述】:

我对 ReactJS 比较陌生,并且是 javascript 新手,并且一直在关注一些在线教程来学习 ReactJS。我遇到了来自不同版本的教程和信息的混合体,所以我确定我要么完全不理解某个主题,要么在这里混淆了。

我的***对象 App 中有一个函数 updateActiveFlag,我将它作为道具传递给 ItemGroup,然后传递给 选中复选框时我想要调用的项目。最终,当我明白自己做错了什么时,我也会以同样的方式修改状态的其他方面。

当我选中复选框时,我进入控制台:

未定义 未定义 4 // 假设我选择了第 5 个复选框,这方面工作正常

谁能帮助解释我所犯的错误。似乎当我回到***处理程序时,“this”的概念已经丢失。目前我对使用某些库来解决这个问题不感兴趣,除非那是唯一的方法。我希望可以在这个例子中解决它,以便我可以首先更好地理解底层方面,然后如果存在的话,我可以考虑一个更合适的方法。

编辑:

现在可以了

对这篇文章的一些回复强调了我在示例中犯的一个错字。我将代码复制并粘贴到一个更大的原型中,并将 ItemGroup 和 Item 中的签名混合在一起,以便在示例代码中体现出来。

我还根据该线程中的反馈再次更改了在 App 控件中传递事件处理程序的方式,现在它可以按我的需要工作。

最后,被引用的重复主题有更多信息来帮助我更好地理解这一点。 在这种情况下,我不确定如何相信答案。

const Item = (props) => 
return (
      <li className="row">
         <input className="col-sm-1" type="checkbox" checked=props.item.Active onChange=() => props.activeFlagHandler(props.index) />
         <div className="col-sm-2">props.index</div>
         <div className="col-sm-3">props.item.Name</div>
         <div className="col-sm-3">props.item.Desc</div>
         <div className="col-sm-3">props.item.Amount</div>
      </li>
   );
;


const ItemGroup = (props) => 
   return (
      <div className="container">
         <h4>props.name</h4>
      <ul>
            props.items.map((item, index) => <Item item=item index=index activeFlagHandler=props.activeFlagHandler/>)
      </ul>
      </div>
   );
;


class App extends React.Component 

   constructor(props) 
      super(props);
      this.state = 
         Name: "",

         "Accounts": [],
         "Expenses": []
      ;
   ;


   loadModel( model ) 
      $.getJSON( 'api/UnitTest' ).then();

      // Using arrow function otherwise would get an error saying setState is not a valid function
      // because of binding. Arrow function passes ensures correct execution context is passed along
      $.getJSON( '/Model/0123456789' ).then( (results) =>  this.processModel( results )  );
   ;


   processModel( results ) 
      console.log( results );

      this.setState( results );
   ;


   updateActiveFlag( index ) 
         //const newState = Object.assign( , this.state );
         console.log( this.state );
         console.log( this.prevState );

         console.log( index );
   ;


   componentDidMount() 
      this.loadModel( '0123456789' );
   


   render() 
      return (
         <div>
            <h2>Hello World  this.state.Name </h2>
            <ItemGroup name="Expenses" items=this.state.Expenses activeFlagHandler=(index)=>this.updateActiveFlag(index) />
         </div>
      );
   


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

感谢您的帮助 强文本

【问题讨论】:

我不确定您在 updateActiveFlag 方法中要做什么。您是否尝试从复选框本身获取信息?我会说 prevState 在那种情况下不存在。 @JayJordan 此时我试图理解为什么我无法在处理程序中访问 this.state 或 this.prevState。一旦我可以访问状态,我将使用提供的索引进行实际工作。谢谢。 基本上将所有函数更改为箭头函数,这样 this 就不会在回调中丢失。看看是否有效 除了按照副本解决绑定问题外,还需要将&lt;input className="col-sm-1" type="checkbox" checked=props.item.Active onChange=props.activeFlagHandler(props.index) /&gt;改为&lt;input className="col-sm-1" type="checkbox" checked=props.item.Active onChange=() =&gt; props.activeFlagHandler(props.index) /&gt;,注意onChange改为箭头函数,否则每次渲染都会调用onChange函数 @ShubhamKhatri 我尝试了一些类似于您向我展示的副本的变体,但可能会出现与无法将箭头函数定义为类属性相关的错误。 ***.com/questions/41398645/…。您的回答也让我意识到我的示例代码中有错字,我从更大的应用程序中复制并粘贴了该代码。我将用我的新发现编辑这个问题。谢谢。 【参考方案1】:

您关于this 正在改变的假设是正确的。在 JavaScript 中,this 取决于调用函数的位置(所谓的执行上下文)。解决这个问题的方法很少,就是使用像这样的bind 方法

 constructor()
   //...
   this.updateActiveFlag = this.updateActiveFlag.bind(this)
 

这样this 将保持不变 (App) 无论从何处调用函数(人为更改为 声明上下文)。传递绑定方法时使用直接形式。

 activeFlagHandler=props.activeFlagHandler

传递函数本身而不是箭头函数形式

 activeFlagHandler=() => props.activeFlagHandler(props.index)  

它传递了一个新的匿名函数。 您的代码中的另一个问题是,您实际上传递给 Item 的是一个匿名函数,它不接收任何参数 (() =&gt; ...),但在 Item 内部,您尝试将参数传递给它 onChange=props.activeFlagHandler(props.index),这是不必要的。 在我看来,你有一个正确的想法,一次只关注一个库,我强烈推荐的一个很好的资源是反应 official docs 特别是 thinking in react 非常有启发性。

【讨论】:

以上是关于ReactJS V16如何将父函数传递给孙事件处理程序[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何将子函数的参数传递给父 reactjs

从reactjs中的父组件调用并将参数传递给子组件的函数

拼接的html字符串中如何将对象作为参数传递给事件处理函数

将函数传递给reactjs中的子组件

将函数传递给 jquery On 事件处理程序

如何将自定义参数传递给事件处理程序