CodingMeUp / AboutFE

知识归纳、内容都在issue里
74 stars 14 forks source link

9、React Vue 相关 #10

Open CodingMeUp opened 6 years ago

CodingMeUp commented 6 years ago

调用 setState 之后发生了什么?

回答1

回答2

所谓的同步异步, 更准确的说法是是否进行了批处理。 对于React 17来说,批处理是通过标识位来实现的,在合成事件中以及hook中setState方法都是进行了批处理的;由于batchUpdate方法本身是同步的,因此setTimeout会导致标识位的设定不符合预期,从而出现批处理失败(转为同步)的情况;在SetTimeout中我们可以用手动批处理的方式实现批处理(ReactDOM.unstable_batchedUpdates);因此,React 17的批处理又可以称为半自动批处理。

对于React 18来说,批处理是通过优先级,以及优先级调度来实现的,因此在原生事件和setTimeout中都可以进行批处理。因此,React 17的批处理又可以称为自动批处理。当然,我们也可以使用flushSync的方法将异步转化为同步处理当前调度~

React 17采用标识位isBatchUpdate来判断是否进行批量更新

(1)将标识位isBatchUpdate置为true (2)将合成事件重所有的setState状态存储到一个quque中 (3)合成事件执行结束设置标识位isBatchUpdate置为false,并恢复之前的queue (4)最后统一获取queue中的数据,进行update

React 18通过优先级lane进行批量更新

批处理是 React 将多个状态更新分组到一个重新渲染中以获得更好的性能。如果没有自动批处理,我们只能在 React 事件处理程序中批处理更新。默认情况下,Promise、setTimeout、原生事件处理程序或任何其他事件内部的更新不会在 React 中批处理。使用自动批处理,这些更新将自动批处理, 四次都是异步的都是批处理的, 提供了flushSync方法, 其本质就是把传入的任务设置为高优先级,把当前处理的调度优先级改为该update的优先级,可以实现同步,有了含有优先级的update对象,并被挂在到fiber上后,就要开始我们的调度了,这也是react 18实现自动批处理的关键

CodingMeUp commented 6 years ago

在生命周期中的哪一步你应该发起 AJAX 请求?

CodingMeUp commented 6 years ago

React 中的事件处理逻辑

CodingMeUp commented 6 years ago

React解决了什么问题

CodingMeUp commented 6 years ago

React 中 SOLID五大原则

这么说你可能没什么太大感觉,也不明白和“依赖”和“反转”有什么关系,说到底其实是一个控制权的问题。常规情况下当你在用express编写一个server时,代码是这样的:

const app = express();
module.exports = function (app) {
    app.get('/newRoute', function(req, res) {...})
};

这意味着你正在编写的这个模块负责了/newRoute这个路径的处理,这个模块在掌握着主动权。 而用依赖反转的写法是:

module.exports = function plugin() {
    return {
        method: 'get',
        route: '/newRoute',
        handler: function(req, res) {...}
    }
}

意味着你把控制权交给了引用这个模块的框架,这样的对比就体现了控制权的反转。 其实前端编程中常常用到这个原则,注入依赖就是对这个思维的体现。比如requireJS和Angular1.0中对依赖模块的引用使用的都是注入依赖的思想。

CodingMeUp commented 6 years ago

组件的Render函数在何时被调用

CodingMeUp commented 6 years ago

组件的生命周期有哪些

CodingMeUp commented 6 years ago

组件的优化

CodingMeUp commented 6 years ago

React Vue Redux Vuex

CodingMeUp commented 6 years ago

Vue 双向绑定是如何实现的

第 29 题:聊聊 Vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的

利用Proxy实现一个简化版的MVVM 参照vue的响应式设计模式,将数据劫持部分的Obejct.defineProperty替换为Proxy即可,其他部分,如compile(编译器没有实现,用写好的html模拟已完成编译),watcher,dep,事件监听等基本保持不变,简单实现代码如下:

 <!-- html部分 -->
 <div id="foo"></div>
 <input type="text" name="" id="bar"/>
 // js部分
 class Watcher{
    constructor(cb){
        this.cb = cb;
    }
    update(){
        this.cb()
    }
 }
 class Dep{
    constructor(){
        this.subs = [];
    }
    publish(){
        this.subs.forEach((item)=>{
            item.update && item.update();
        })
    }
 }
 class MVVM{
    constructor(data){
        let that = this;
        this.dep = new Dep();
        this.data = new Proxy(data,{
            get(obj, key, prox){
                that.dep.target && that.dep.subs.push(that.dep.target);
                return obj[key]
            },
            set(obj, key, value, prox){
                obj[key] = value;
                that.dep.publish();
                return true;
            }
        })
        this.compile();
    }
    compile(){

        let divWatcher = new Watcher(()=>{
            this.compileUtils().div();
        })
        this.dep.target = divWatcher;
        this.compileUtils().div();
        this.dep.target = null;

        let inputWatcher = new Watcher(()=>{
            this.compileUtils().input();
        })
        this.dep.target = inputWatcher;
        this.compileUtils().input();
        this.compileUtils().addListener();
        this.dep.target = null;
    }
    compileUtils(){
        let that = this;
        return {
            div(){
                document.getElementById('foo').innerHTML = that.data.foo;
            },
            input(){
                document.getElementById('bar').value = that.data.bar;
            },
            addListener(){
                document.getElementById('bar').addEventListener('input', function(){
                    that.data.bar = this.value;
                })
            }
        }
    }
 }
 let mvvm = new MVVM({foo: 'foo233', bar: 'bar233'})

通过mvvm.data.foo或者mvvm.data.bar可以操作数据,可以观察到view做出了改变;在输入框改变输入值,也可以通过mvvm.data观察到数据被触发改变

CodingMeUp commented 6 years ago

React Fiber 纤维比Thread更细

CodingMeUp commented 6 years ago

VDOM

https://github.com/livoras/blog/issues/13

CodingMeUp commented 6 years ago

_20171115174855

React-Redux 实现

CodingMeUp commented 6 years ago

Vue React 生命周期 image image

CodingMeUp commented 4 years ago

传统的DIFF 和 React Diff Vue Diff

CodingMeUp commented 4 years ago

第 29 题:聊聊 Vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的

CodingMeUp commented 4 years ago

第 32 题:Virtual DOM 真的比操作原生 DOM 快吗?谈谈你的想法

不要天真地以为 Virtual DOM 就是快,diff 不是免费的,batching 么 MVVM 也能做,而且最终 patch 的时候还不是要用原生 API。在我看来 Virtual DOM 真正的价值从来都不是性能,而是它

  1. 为函数式的 UI 编程方式打开了大门;
  2. 可以渲染到 DOM 以外的 backend,比如 ReactNative。