7-4 事件
1. event 是 SyntheticEvent ,模拟出来 DOM 事件所有能力
2. event.nativeEvent 是原生事件对象
3. 所有的事件,都被挂载到 document 上
4. 和 DOM 事件不一样,和 Vue 事件也不一样
修改事件this指向
constructor() { this.clickHandler = this.clickHandler.bind(this) }
<button onClick={this.clickHandler}> </button>
clickHandler() { this.setState({}, cb) }
每次点击都会只执行bind, 不推荐 <button onClick={this.clickHandler.bind(this)}> </button>
静态方法 ,this指向当前实例
<button onClick={this.clickHandler}> </button>
clickHandler = () => { }
回调中使用箭头函数(官方推荐)
<button onClick={() => this.clickHandler()}> </button>
clickHandler() {}
7-5 关于event参数
clickhandler = (event) => {
event.preventDefault()
event.stopPropagation()
}
event 不是原生event, 经过react封装, event.proto.consturctor = SyntheticEvent
react中如何获取原生event呢?event.nativeEvent
- event
- event.target 指向当前元素, 即当前元素触发
- event.currentTarget
- event.nativeEvent
- event.nativeEvnet.target 指向当前元素, 即当前元素触发
- event.nativeEvent.currenttarget 指向 documnet
传递自定义参数(最后一个参数接受event)
Function.prototype.bind(不推荐)
<button onClick={this.clickHandler.bind(this, id, name)}> </button>
clickHandler(id, name, event) { }
回调中使用箭头函数
<button onClick={() => this.clickHandler(id, name, event)}> </button>
clickHandler(id, name, event) { }
7-6 表单
- 受控组件
- input、textarea、select用value
checkbox、radio用checked
<input value={this.state.name} onChange={this.onChange}>
onChange = () => {
this.setState({ name: e.target.value }) }
7-7 父子组件通信
props 传递数据
- props 传递函数
- props 类型检查
状态(数据)提升, 即父组件管理数据, 子组件负责渲染。
🌟7-8 setState使用不可变值
- 不可变值
- 可能是异步更新
- 可能会被合并
构造函数中定义 constructor (props) { super(props) this.state = { counter: 0 } }
不可变值(函数式编程, 纯函数)。 不能直接操作。setState之前不可修改state的值。
this.setState({ count: this.state.count + 1})
this.setState({ // 数组
l1: this.state.l1.concat('new'), // 追加, 不可使用push
l1: [...this.state.l1, 'new'], // 追加
l2: this.state.l2.slice() // 拷贝/截取
l3: this.state.l3.filter })
this.setState({ // 对象
obj1: Object.assign({}, this.state.obj1, {new: 'new'}),
obj1: {...this.state.obj1, {new: 'new'}} })
可能是异步更新
⚠️ 1. setState直接使用是异步。 2. setTimeout中的setState是同步。 3. 自定义的事件中setState是同步。
this.setState({}, cb)
setTimeout(() => {
this.setState()
}, 0)
clickHandler = () => {
this.setState()
cb
}
componentDidMount () {
document.body.addEventListener('click', clickHandler)
}
componentWillUnmount () {
document.body.removeEventListener('click', clickHandler)
}
可能会被合并。
传入对象, 会被合并(类似于Object.assign)。 传入函数, 不会被合并。
this.setState((prevState, props) => {
return { count: prevState.count + 1 } })