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'), // 追加, 不可使用pushl1: [...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 } })
