如何在 React 子组件中设置事件处理程序
简介 使用 React 子组件是一种在组件中使用多个组件的做法,可将复杂的层次结构分解为小型、独立且可重复使用的组件。这些子组件可以配置为通过 props 处理事件和数据。“Props”代表属性,是 React 的一项功能,可在组件之间以不可变的键值对对象的形式传递数据。
实现子组件相当简单,但有时使用匿名函数或 React 类来保留上下文可能比较棘手。本指南介绍了在 React 中使用匿名和 ES6 功能实现子组件。
在 React 组件中实现事件
可以通过扩展Component类来创建 React 类组件,并使用函数实现onClick事件来处理点击:
import React, { Component } from 'react';
export default class App extends Component {
handleClick() {
console.log("click");
}
render() {
return (
<div className="container">
<button onClick={this.handleClick} > click </button>
</div>
);
}
}
在上面的代码片段中,只要单击按钮,就会触发handleClick函数。无需将handleClick与this绑定,因为handleClick不会从其容器 ( App ) 组件访问任何内容。否则,就会出现错误,因为this在运行时指向的是window对象,而不是App。
将事件处理程序传递给子组件
子组件可以作为类或函数组件实现。可以使用函数组件优化实现。Address 子组件将通过props从容器组件接收详细信息:
function Address({ type, houseNo, clickHandler }) {
const isPermanent = type && type === 'Temporary';
return (
<div>
<b>{type}</b>
<p>{houseNo}
{' '}
{isPermanent ? <button onClick={clickHandler} title='Delete'>X</button> : ''}
</p>
</div>
)
}
Address组件使用解构赋值{ type, houseNo, clickHandler }来直接访问传递的prop值。clickHandler是一个处理点击的函数,它被传递给onClick属性。
App组件使用state来存储地址的数据,removeTempAddress函数将仅使用永久对象重置地址对象的值:
export default class App extends Component {
// set the values for the addresses in state object
state = {
addresses: {
permanent: {
houseNo: 'ABC',
},
temporary: {
houseNo: 'XYZ',
}
}
}
// an arrow function to retails the context of this
removeTempAddress = () => {
const { permanent } = this.state.addresses;
// reset value of 'addresses' to 'permanent' only
this.setState({ addresses: { permanent } })
}
render() {
const { permanent, temporary } = this.state.addresses;
return (
<div className="container">
<Address type='Permanent' houseNo={permanent.houseNo} />
{temporary && <Address type='Temporary' houseNo={temporary.houseNo} clickHandler={this.removeTempAddress} />}
</div>
);
}
}
通过 props 传递事件处理程序可将控制权交给容器组件来处理事件,并有助于创建可重用的组件。
在运行时实现子组件
在运行时生成子组件是动态 UI 的常见要求。通常,UI 必须根据数据项列表中的变化进行渲染/更新,例如,显示购物车中的商品、库存的表格数据等。由于数据的大小是动态的,解决方案是在生成项目时迭代数据。使用数组映射是一种迭代数据值进行处理的常用方法。它需要一个匿名函数来处理数组的元素,并且可以使用箭头函数在匿名函数内访问上下文(App组件):
export default class App extends Component {
state = {
items: ["Banana", "Mango"],
};
handleClick(event) {
console.log(event.target.innerHTML);
}
render() {
var listItems = this.state.items.map((item, index) => {
return <li key={index} onClick={this.handleClick}><a href='/#'>{item}</a></li>;
});
return (
<div className="container">
<ul>{listItems}</ul>
</div>
);
}
}
使用箭头函数可以通过保留上下文来访问this.handleClick 。或者, map函数也将this作为参数来保留上下文:
var listItems = this.state.items.map(function (item, index) {
return <li key={index} onClick={this.handleClick}><a href='/#'>{item}</a></li>;
}, this); // this as second argument to map function
这也可以使用bind来完成:
var listItems = this.state.items.map(function (item, index) {
return <li key={index} onClick={this.handleClick}><a href='/#'>{item}</a></li>;
}.bind(this)); // binding this with anonymous function
结论
子组件是创建可重用元素以及通过 props 传递事件和数据的绝佳方式。在运行时,默认情况下this指的是窗口对象,并且有很多方法可以通过箭头函数、传递this 的重载方法和bind方法在动态子组件中保留上下文。希望本指南解释了以不同方式创建子组件的必要细节。祝您编码愉快!
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~