[聚焦React]7-1React基本使用 - 图17-4 事件
    1. event 是 SyntheticEvent ,模拟出来 DOM 事件所有能力
    2. event.nativeEvent 是原生事件对象
    3. 所有的事件,都被挂载到 document 上
    4. 和 DOM 事件不一样,和 Vue 事件也不一样
    修改事件this指向

    1. constructor() { this.clickHandler = this.clickHandler.bind(this) }
    2. <button onClick={this.clickHandler}> </button>
    3. clickHandler() { this.setState({}, cb) }

    每次点击都会只执行bind, 不推荐 <button onClick={this.clickHandler.bind(this)}> </button>
    静态方法 ,this指向当前实例

    1. <button onClick={this.clickHandler}> </button>
    2. clickHandler = () => { }

    回调中使用箭头函数(官方推荐)

    1. <button onClick={() => this.clickHandler()}> </button>
    2. clickHandler() {}

    7-5 关于event参数

    1. clickhandler = (event) => {
    2. event.preventDefault()
    3. event.stopPropagation()
    4. }

    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(不推荐)

    1. <button onClick={this.clickHandler.bind(this, id, name)}> </button>
    2. clickHandler(id, name, event) { }

    回调中使用箭头函数

    1. <button onClick={() => this.clickHandler(id, name, event)}> </button>
    2. clickHandler(id, name, event) { }

    7-6 表单

    • 受控组件
    • input、textarea、select用value
    • checkbox、radio用checked

      1. <input value={this.state.name} onChange={this.onChange}>
      2. onChange = () => {
      3. this.setState({ name: e.target.value }) }

      7-7 父子组件通信

    • props 传递数据

    • props 传递函数
    • props 类型检查

    状态(数据)提升, 即父组件管理数据, 子组件负责渲染。
    🌟7-8 setState使用不可变值

    • 不可变值
    • 可能是异步更新
    • 可能会被合并

    构造函数中定义 constructor (props) { super(props) this.state = { counter: 0 } }
    不可变值(函数式编程, 纯函数)。 不能直接操作。setState之前不可修改state的值。

    1. this.setState({ count: this.state.count + 1})
    2. this.setState({ // 数组
    3. l1: this.state.l1.concat('new'), // 追加, 不可使用push
    4. l1: [...this.state.l1, 'new'], // 追加
    5. l2: this.state.l2.slice() // 拷贝/截取
    6. l3: this.state.l3.filter })
    7. this.setState({ // 对象
    8. obj1: Object.assign({}, this.state.obj1, {new: 'new'}),
    9. obj1: {...this.state.obj1, {new: 'new'}} })

    可能是异步更新
    ⚠️ 1. setState直接使用是异步。 2. setTimeout中的setState是同步。 3. 自定义的事件中setState是同步。

    1. this.setState({}, cb)
    2. setTimeout(() => {
    3. this.setState()
    4. }, 0)
    5. clickHandler = () => {
    6. this.setState()
    7. cb
    8. }
    9. componentDidMount () {
    10. document.body.addEventListener('click', clickHandler)
    11. }
    12. componentWillUnmount () {
    13. document.body.removeEventListener('click', clickHandler)
    14. }

    可能会被合并。
    传入对象, 会被合并(类似于Object.assign)。 传入函数, 不会被合并。

    1. this.setState((prevState, props) => {
    2. return { count: prevState.count + 1 } })