*遗留问题(跨页面组件传值封装(类组件))
import React, { Component } from "react";
import Cards from "./compontens/Cards";
export default class App extends Component {
// 类成员 属性 方法
// 属性 不需要const 或者 let var 等修饰
arr = [
{
name: "peilong",
job: "P5前端工程师",
sex: "男",
},
{
name: "cc",
job: "前端工程师",
sex: "男",
},
];
render() {
return (
<div>
App
{this.arr.map((item) => (
<Cards data={item} key={item.id}></Cards>
))}
</div>
);
}
}
import React, { Component } from 'react'
export default class Cards extends Component {
render() {
const {name,job,sex} = this.props.data
return (
<div style={{border: '1px solid aqua', padding: 10}}>
<div>姓名: {name}</div>
<div>职位: {job}</div>
<div>性别: {sex}</div>
</div>
)
}
}
1.事件绑定
React元素的事件处理和DOM元素的很相似,但是有一点语法上的不同。React元素的事件绑定采用on+事件名
的方式来绑定一个事件,注意,这里和原生的事件是有区别的,原生的事件全是小写,如onclick
, React里的事件是驼峰如onClick
,React的事件并不是原生事件,而是合成事件。
在React里,类组件与函数组件绑定事件是差不多的,只是在类组件中绑定事件函数的时候需要用到this
,代表指向当前的类的引用,在函数中不需要调用this
关键词。
函数组件事件绑定:
import React from "react";
const clickHandler = () => {
console.log("海纳百川有容乃大,壁立千仞无欲则刚。");
};
const App = () => {
return <button onClick={clickHandler}>老林说</button>;
};
export default App;
类组件事件绑定:
import React, { Component } from "react";
export default class App extends Component {
// 类内调用属性方法必须用this调用
render() {
return (
<div>
<button onClick={this.handleClick}>点击我</button>
</div>
);
}
// 类中方法 不需要写function关键字
handleClick(){
console.log('输出');
}
}
注意点:
在写事件的时候,调用时如果不涉及传参的话,一定不要加
()
,加了就错。在类组件中写事件处理程序的时候,不能写标准的
function xxx () {}
,写了就报错,一定要用简化的写法或者箭头函数形式事件处理属性名称(事件绑定时用的属性)一定要使用符合react的小驼峰写法
2.this指向问题
在JSX事件函数方法中的this,默认不会绑定this指向。如果我们忘记绑定,当我们调用这个函数的时候this的值为undefined。所以使用时一定要绑定好this的指向!
例如,像下面这段代码回调函数中的this
输出为undefined
:
import React, { Component } from "react";
export default class App extends Component {
text = '选我好不好'
// 类内调用属性方法必须用this调用
// 在JSX事件函数方法中的this,默认不会绑定this指向。
render() {
return (
<div>
{/* 修改this指向*/}
{/* this绑定方式
1.bind 绑定 方法不调用 不立即执行
2.apply 绑定立即调用 传值不一样 数组
3.call 绑定立即调用 传值不一样 传递每一个参数
*/}
{/** 第一个 button 点击事件 */}
<button onClick={this.handleClick}>点击我</button>
<button onClick={this.handleClicks.bind(this)}>点击我</button>
</div>
);
}
// 类中方法 不需要写function关键字
// 时间处理方法的this 指向undefind
handleClick(){
console.log(this) // 输出undefind
console.log(this.text);
}
handleClicks(){
console.log(this) // 输出正常的指向内容
console.log(this.text);
}
}
解决上面出现的this
指向问题的方式有以下几种:
import React, { Component } from 'react'
/**
* 1.this 丢失指向问题解决方案 bind
*/
export default class App extends Component {
// 方法三 在构造函数进行绑定
// 构造函数 在对象被实例化是 会触发
constructor(){
// 调用父类方法
super()
console.log(this);
this.add = this.add.bind(this)
}
num = 100
// 方法一
add(){
console.log(this.num);
}
// 方法二
add1 = () =>{
//箭头函数没有this指向, 向上级保持
console.log(this.num);
}
// 方法四
add2(){
console.log(this.num);
}
render() {
return (
<div>
{/** 方法1 通过bind绑定this */}
<button onClick={this.add.bind(this)}>{this.num}</button>
{/** 方法2 事件处理方法定义为箭头函数 该箭头函数不写() 表示事件执行时才调用*/}
<button onClick={this.add1}>{this.num}</button>
{/** 方法3 在构造函数进行绑定 */}
<button onClick={this.add}>{this.num}</button>
{/** 方法4 事件触发箭头函数 因为箭头函数没有 this指向 箭头函数调用事件处理函数 this指向保持正常 ()写括号表示立即调用 */}
<button onClick={()=> this.add2()}>{this.num}</button>
</div>
)
}
}
3.事件方法传参
React中对于事件方法传参的方式有着非常灵活的用法。以传递参数username
值为zhangsan
为例,常见的有以下几种方式:
通过this.事件方法.bind
(bind为绑定数据)方式进行传参(推荐),例如:
`onClick={this.clickHandler.bind(this,'zhangsan')}`
- 对应的形参接收:`clickHandler(username)`
`onClick={this.clickHandler.bind(this,'zhangsan')}`
- 对应的形参接收:`clickHandler(username,event)`
使用箭头函数传参,例如:
`onClick={() => this.事件方法('zhangsan')}`
- 对应的形参接收:`clickHandler(username)`
`onClick={(e) => this.事件方法('zhangsan',e)}`
- 对应的形参接收:`clickHandler(username,event)`
4.事件对象
React中可以通过事件处理函数的参数获取到事件对象,它的事件对象叫做:合成事件,即兼容所有浏览器,无需担心跨浏览器兼容问题。这个对象和之前学习的事件对象所包含的方法和属性都基本一致,不同的是React中的事件对象并不是浏览器提供的,而是它自己内部所构建的。此事件对象拥有和浏览器原生事件相同的接口,包括stopPropagation()
和 preventDefault()
,如果我们想获取到原生事件对象,可以通过e.nativeEvent
属性来进行获取。
import React, { Component } from "react";
class App extends Component {
render() {
return (
<div>
<button onClick={this.clickHandler}>老林说</button>
</div>
);
}
clickHandler(e) {
console.log("海纳百川有容乃大,壁立千仞无欲则刚。");
// react构建的事件对象
console.log(e);
// 浏览器原生的事件对象
console.log(e.nativeEvent);
// 事件对应的DOM对象
console.log(e.target);
// 事件对应的DOM对象的内嵌HTML
console.log(e.target.innerHTML);
}
}
export default App;
案例:
import React, { Component } from 'react'
export default class App extends Component {
handleClick(e){
// react事件对象为合成事件对象 兼容各种浏览器
// nativeEvent 原生事件对象
// target DOM对象 事件目标
console.log(e);
console.log(e.target);
e.target.style.backgroundColor = 'aqua'
e.target.innerText = 'hello'
// 阻止事件冒泡
e.stopPropagation()
}
clickdiv(e){
console.log('选我了');
}
render() {
return (
<div onClick={this.clickdiv}>
<button onClick={this.handleClick}>你好</button>
<a href="https://www.csdn.net/" onClick={this.go}>csdn</a>
</div>
)
}
go(e){
// 阻止默认行为
e.preventDefault()
// 阻止事件冒泡
e.stopPropagation()
// 跳转页面
window.location.href = 'https://www.csdn.net/'
}
}