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 就不会在回调中丢失。看看是否有效 除了按照副本解决绑定问题外,还需要将<input className="col-sm-1" type="checkbox" checked=props.item.Active onChange=props.activeFlagHandler(props.index) />
改为<input className="col-sm-1" type="checkbox" checked=props.item.Active onChange=() => props.activeFlagHandler(props.index) />
,注意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
的是一个匿名函数,它不接收任何参数 (() => ...
),但在 Item
内部,您尝试将参数传递给它 onChange=props.activeFlagHandler(props.index)
,这是不必要的。
在我看来,你有一个正确的想法,一次只关注一个库,我强烈推荐的一个很好的资源是反应 official docs 特别是 thinking in react 非常有启发性。
【讨论】:
以上是关于ReactJS V16如何将父函数传递给孙事件处理程序[重复]的主要内容,如果未能解决你的问题,请参考以下文章