zoukankan      html  css  js  c++  java
  • react进阶第二讲——component

    Class组件

    在 class 组件中,除了继承 React.Component ,底层还加入了 updater 对象,组件中调用的 setState 和 forceUpdate 本质上是调用了 updater 对象上的 enqueueSetState 和 enqueueForceUpdate 方法。

    function Component(props, context, updater) {
      this.props = props;      //绑定props
      this.context = context;  //绑定context
      this.refs = emptyObject; //绑定ref
      this.updater = updater || ReactNoopUpdateQueue; //上面所属的updater 对象
    }
    /* 绑定setState 方法 */
    Component.prototype.setState = function(partialState, callback) {
      this.updater.enqueueSetState(this, partialState, callback, 'setState');
    }
    /* 绑定forceupdate 方法 */
    Component.prototype.forceUpdate = function(callback) {
      this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
    }
    

    Q: 如果没有在 constructor 的 super 函数中传递 props,那么接下来 constructor 执行上下文中就获取不到 props ,这是为什么呢?

    /* 假设我们在 constructor 中这么写 */
    constructor(){
        super()
        console.log(this.props) // 打印 undefined 为什么?
    }
    

    函数组件

    不要给函数组件 prototype 绑定属性或方法,因为React 对函数组件的调用,是采用直接执行函数的方式,而不是通过new的方式。

    函数组件和类组件本质的区别:

    对于类组件来说,底层只需要实例化一次,实例中保存了组件的 state 等状态。对于每一次更新只需要调用 render 方法以及对应的生命周期就可以了。但是在函数组件中,每一次更新都是一次新的函数执行,一次函数组件的更新,里面的变量会重新声明。

    组件通信方式

    1. props 和 callback 方式
    2. ref 方式。
    3. React-redux 或 React-mobx 状态管理方式。
    4. context 上下文方式。
    5. event bus 事件总线。

    这里指讲解event bus事件总线。

    import { BusService } from './eventBus'
    /* event Bus  */
    function Son(){
        const [ fatherSay , setFatherSay ] = useState('')
        React.useEffect(()=>{ 
            BusService.on('fatherSay',(value)=>{  /* 事件绑定 , 给父组件绑定事件 */
                setFatherSay(value)
           })
           return function(){  BusService.off('fatherSay') /* 解绑事件 */ }
        },[])
        return <div className='son' >
             我是子组件
            <div> 父组件对我说:{ fatherSay } </div>
            <input placeholder="我对父组件说" onChange={ (e)=> BusService.emit('childSay',e.target.value)  }   />
        </div>
    }
    /* 父组件 */
    function Father(){
        const [ childSay , setChildSay ] = useState('')
        React.useEffect(()=>{    /* 事件绑定 , 给子组件绑定事件 */
            BusService.on('childSay',(value)=>{
                 setChildSay(value)
            })
            return function(){  BusService.off('childSay') /* 解绑事件 */ }
        },[])
        return <div className="box father" >
            我是父组件
           <div> 子组件对我说:{ childSay } </div>
           <input placeholder="我对子组件说" onChange={ (e)=> BusService.emit('fatherSay',e.target.value) }   />
           <Son  />
        </div>
    }
    
    // event.ts
    export interface Listener {
        cb: Function
        once: boolean
    }
    
    export interface EventsType {
        [eventName: string]: Listener[]
    }
    
    
    export default class OnFire {
        static ver = '__VERSION__'
    
        es: EventsType = {}
    
        on(eventName: string, cb: Function, once: boolean = false) {
            if (!this.es[eventName]) {
                this.es[eventName] = []
            }
    
            this.es[eventName].push({
                cb,
                once,
            })
        }
    
    
        once(eventName: string, cb: Function) {
            this.on(eventName, cb, true)
        }
    
        fire(eventName: string, ...params: any[]) {
            const listeners = this.es[eventName] || []
            let l = listeners.length
    
            for (let i = 0; i < l; i++) {
                const { cb, once } = listeners[i]
    
                cb.apply(this, params)
    
                if (once) {
                    listeners.splice(i, 1)
                    i--
                    l--
                }
            }
        }
    
        off(eventName?: string, cb?: Function) {
            if (eventName === undefined) {
                this.es = {}
            } else {
                if (cb === undefined) {
                    delete this.es[eventName]
                } else {
                    const listeners = this.es[eventName] || [];
                    let l = listeners.length
                    for (let i = 0; i < l; i++) {
                        if (listeners[i].cb === cb) {
                            listeners.splice(i, 1);
                            i--
                            l--
                        }
                    }
                    console.log(listeners, eventName, 'listeners')
                }
            }
        }
    
        emit = this.fire
    }
    
    export const BusService = new OnFire()
    
    

    eventBus违背了 React 单向数据流原则,一般不推荐使用。

  • 相关阅读:
    详细版Jmeter随机参数的接口并发测试总结
    Windows下MQTT代理服务器的搭建
    关于使用elascticsearch的两个小技巧
    解决easyswoole的swServer_start_check: onTask event callback must be set at报错
    解决使用宝塔安装的swoole扩展,运行项目出现的3个常见问题
    浅谈一下ThinkPHP5.1实现事务嵌套的特性
    资源出现多个 "Access-Control-Allow-Origin"
    Mac 制作系统启动盘
    深入剖析分布式一致性共识算法
    分布式系统限流算法分析与实现
  • 原文地址:https://www.cnblogs.com/renzhiwei2017/p/15617490.html
Copyright © 2011-2022 走看看