内置组件事件
内置组件: jsx中html标签其实是内置组件,可以直接使用dom原生事件
import React from 'react';
import ReactDOM from 'react-dom/client';
function myClick(e) {
console.log('点击了', e)
}
const a = 123, b = 456;
const h1 = (
<h1 onClick={myClick}>Hello World
<span>{a} * {b} = {a*b}</span>
</h1>
)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{h1}
</React.StrictMode>
);
自定义组件的事件
react事件的本质: 其实就是一个属性
下例中,模拟当倒计时结束时调用父组件的onOver事件
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import TickControl from './components/TickControl';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<TickControl />
</React.StrictMode>
);
这里会有一个this指向问题,需要注意一下
解决this指向问题还有别的办法,自行百度
TickControl.js
import React, { Component } from 'react'
import Tick from './Tick'
export default class TickControl extends Component {
state = {
isOver: false // 倒计时是否完成
}
// 当写成箭头函数时,将会绑定到对象上而不是原型上
// 传入子组件不会产生this问题
handleOver = () => {
this.setState({
isOver: true
})
}
// 这样定义会绑定到原型上,传入子组件调用会产生this指向问题
// handleOver() {
// this.setState({
// isOver: true
// })
// }
render() {
let status = '正在倒计时...'
if (this.state.isOver) {
status = '倒计时已结束'
}
return (
<div>
<Tick
onOver={this.handleOver}
number={10}
/>
<h1>{status}</h1>
</div>
)
}
}
Tick.js
// 倒计时
import React, { Component } from 'react'
export default class Tick extends Component {
constructor(props) {
super(props)
// state必须初始化且必须为对象,否则默认为undefined
this.state = {
left: this.props.number
}
}
// 使用setState时防止react出警告调用此函数
componentDidMount() {
let timer = setInterval(()=> {
// 每次调用会重新渲染,每次赋值会使用覆盖state而不是替换state
this.setState({
left: this.state.left - 1
})
if (this.state.left === 0) {
clearInterval(timer)
// 当倒计时结束 调用父组件事件
this.props.onOver && this.props.onOver()
}
}, 1000)
}
render() {
return (
<h1>倒计时: {this.state.left} </h1>
)
}
}