事件处理
绑定事件
采用on+事件名的方式来绑定一个事件 这里和原生的事件是有区别的,原生的事件全是小写如onclick,React中的事件是驼峰如onClick React的事件并不是原生事件,而是合成事件
事件handler的写法
直接在render里写行内的箭头函数(不推荐) 看着不爽,污染了html结构
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true
}
}
render ( ) {
return (
< Fragment>
< button onClick = { ( ) => { this . setState ( {
flag: ! this . state. flag
} ) } } > 切换 < / button>
< h3> 直接用箭头函数在render函数中书写 < / h3>
{ this . state. flag && < img src = "/img/img (1).jpg" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true
}
}
change = ( ) => {
this . setState ( {
flag: ! this . state. flag
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { this . change} > 切换< / button>
< h3> 在组件内使用箭头函数来定义方法< / h3>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
直接在组件内定义一个非箭头函数的方法,然后在render里面直接使用 onClick= {this.handleClick.bind(this)}(不推荐)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true
}
}
change ( ) {
this . setState ( {
flag: ! this . state. flag
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { this . change. bind ( this ) } > 切换< / button>
< h3> 在组件内定义非箭头函数的方法,在render里面直接使用并使用bind改变this 指向< / h3>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
直接在组件里面定义一个非箭头函数的方法,然后在constructor里面bind(this)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true
}
this . change= this . change. bind ( this )
}
change ( ) {
this . setState ( {
flag: ! this . state. flag
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { this . change} > 切换< / button>
< h3> 组件内定义非箭头函数方法,构造函数绑定this < / h3>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
Event 对象
和普通浏览器一样,事件handler会被自动传入一个event对象,这个对象和普通的浏览器event对象所包含的方法和属性基本一致。不同的是React中的event对象不是浏览器所提供的,而是它自己内部所构建的,它同样具有event.stopPropagation、event.preventDefault这种常用的方法。 事件对象中的值很多都是null,但是可以正常使用。
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true
}
}
change = ( e) => {
console. log ( e)
console. log ( e. clientX)
this . setState ( {
flag: ! this . state. flag
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { this . change} > 切换< / button>
< h3> event对象< / h3>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
事件的参数传递
在render里调用方法的地方外面包一层箭头函数(比较推荐)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true ,
msg: ''
}
}
change = ( val) => {
this . setState ( {
flag: ! this . state. flag,
msg: val
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { ( ) => { this . change ( 12345 ) } } > 切换图片与文字< / button>
< h3> 事件传参- 方法调用外包一层箭头函数< / h3>
< p> msg: { this . state. msg} < / p>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
在render里通过this.handleEvent.bind(this, 参数)这样的方式来传递,写法如下
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
flag: true ,
msg: ''
}
}
change = ( val) => {
this . setState ( {
flag: ! this . state. flag,
msg: val
} )
}
render ( ) {
return (
< Fragment>
< button onClick= { this . change. bind ( this , 12345 ) } > 切换图片和文字< / button>
< h3> 通过this . handleEvent. bind ( this , 参数) < / h3>
< p> msg: { this . state. msg} < / p>
{ this . state. flag&& < img src= "" / > }
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
比较推荐的是做一个子组件,在父组件中定义方法,通过props传递到子组件中,然后子组件通过this.props.method来调用
import React, { Component} from 'react'
import ReactDom from 'react-dom'
class Son extends Component {
render ( ) {
return (
< div>
< button onClick= { ( ) => { this . props. kick ( 111000 ) } } > kick< / button>
< / div>
)
}
}
class Father extends Component {
constructor ( ) {
super ( )
this . state= {
kick: '踢'
}
}
kick = ( val) => {
this . setState ( {
kick: '踢了好几脚' + val
} )
}
render ( ) {
return (
< div>
< Son kick= { this . kick} / >
< p> { this . state. kick} < / p>
< / div>
)
}
}
ReactDom. render (
< Father/ > ,
document. getElementById ( 'root' )
)
处理用户输入
import React, { Component, Fragment} from 'react'
import ReactDom from 'react_dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
msg: ''
}
}
changeMsg = ( e) => {
this . setState ( {
msg: e. target. value
} )
}
render ( ) {
return (
< Fragment>
< input type= "text" onInput= { this . changeMsg} / >
< p> 展示数据:{ this . state. msg} < / p>
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react_dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
msg: ''
}
}
changeMsg = ( ) => {
this . setState ( {
msg: this . refs. user. value
} )
}
render ( ) {
return (
< Fragment>
< input type= "text" onInput= { this . changeMsg} ref= "user" / >
< p> 展示数据:{ this . state. msg} < / p>
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Event extends Component {
constructor ( ) {
super ( )
this . state= {
msg: ''
}
}
changeMsg = ( ) => {
this . setState ( {
msg: this . user. value
} )
}
render ( ) {
return (
< Fragment>
< input onInput= { this . changeMsg} type= "text" ref= { el=> this . user= el} / >
< p> 展示数据:{ this . state. msg} < / p>
< / Fragment>
)
}
}
ReactDom. render (
< Event/ > ,
document. getElementById ( 'root' )
)
组件通信
父子组件通信
无论父组件传递的是props还是state,子组件都是用props接收
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Son extends Component {
render ( ) {
return (
< Fragment>
< h3> 这里是Son组件 < / h3>
< p> 父亲传递过来的数据:{ this . props. name} < / p>
< / Fragment>
)
}
}
class Father extends Component {
constructor ( ) {
super ( )
this . state= {
name: "二狗子"
}
}
render ( ) {
return (
< Fragment>
< h3> 这是Father组件< / h3>
< Son { ... this . state} / >
< / Fragment>
)
}
}
ReactDom. render (
< Father/ > ,
document. getElementById ( 'root' )
)
子父组件通信
父组件传递方法给子组件,子组件调用父组件传递过来的方法 注意:自己的状态自己更改
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Son extends Component {
render ( ) {
return (
< Fragment>
< h3> 这里是Son组件 < / h3>
< button onClick = { ( ) => { this . props. change ( '张三' ) } } > 改名 < / button>
< p> 父亲传递过来的数据: { this . props. name } < / p>
< / Fragment>
)
}
}
class Father extends Component {
constructor ( ) {
super ( )
this . state = {
name: '二狗子'
}
}
change = ( val ) => {
this . setState ( {
name: val
} )
}
render ( ) {
return (
< Fragment>
< h3> 这里是Father组件 < / h3>
< hr/ >
< Son change = { this . change } / >
< p> name: { this . state. name } < / p>
< / Fragment>
)
}
}
ReactDom. render (
< Father/ > ,
document. getElementById ( 'root' )
)
非父子组件通信 ref函数
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
class Girl extends Component {
render ( ) {
return (
< Fragment>
< button onClick = { this . props. kick } > 揍弟弟 < / button>
< h3> 这里是Girl组件 < / h3>
< / Fragment>
)
}
}
class Son extends Component {
constructor ( ) {
super ( )
this . state = {
flag: false
}
}
change = ( ) => {
this . setState ( {
flag: ! this . state. flag
} )
}
render ( ) {
return (
< Fragment>
< h3> 这里是Son组件 < / h3>
{ this . state. flag && < p> o ( ╥﹏╥) o o ( ╥﹏╥) o o ( ╥﹏╥) o o ( ╥﹏╥) o < / p> }
< / Fragment>
)
}
}
class Father extends Component {
constructor ( ) {
super ( )
}
kick = ( ) => {
console. log ( this )
this . son. change ( )
}
render ( ) {
return (
< Fragment>
< h3> 这里是Father组件 < / h3>
< hr/ >
< Son ref = { el => this . son = el} / >
< Girl ref = { el => this . girl = el } kick = { this . kick } / >
< / Fragment>
)
}
}
ReactDom. render (
< Father/ > ,
document. getElementById ( 'root' )
)
跨组件通信
context 创建上下文React.createContext() 使用上下文包裹目标组件的父组件
< MyContext. Provider value = { this . state. xxx} >
< Father> < / Father>
< / MyContext. Provider>
在目标组件中先定义一个静态属性 static contextType = MyContext 通过 this.context来使用数据
import React, { Component, Fragment} from 'react'
import ReactDom from 'react-dom'
const MyContext = React. createContext ( )
class Son extends Component {
constructor ( ) {
super ( )
}
static contextType = MyContext
render ( ) {
console. log ( this )
return (
< Fragment>
< h3> 这里是Son组件 < / h3>
< p> grandFather 组件给我的数据 { this . context } < / p>
< / Fragment>
)
}
}
class Father extends Component {
constructor ( ) {
super ( )
}
render ( ) {
return (
< Fragment>
< h3> 这里是Father组件 < / h3>
< Son/ >
< / Fragment>
)
}
}
class GrandFather extends Component {
constructor ( ) {
super ( )
this . state = {
name: "mingliang"
}
}
render ( ) {
return (
< Fragment>
< h3> 这里是爷爷组件 < / h3>
< hr/ >
< MyContext. Provider value = { this . state. name } >
< Father/ >
< / MyContext. Provider>
< / Fragment>
)
}
}
ReactDom. render (
< GrandFather/ > ,
document. getElementById ( 'root' )
)