学习笔记(11)

5 篇文章 1 订阅

学习笔记(11)

最近在整理一些零碎的知识点,发现自己原来的一些认知并不正确,特此记录。

react和vue到底什么区别?

vue和react的区别及各自优点
关于Vue和React区别的一些笔记
简单层面

  • 语法不同
  • 对于redux router的维护不同

复杂层面

  • 监听数据变化的原理不同
    • react:比较引用,通过pureComponent/shouldComponentUpdate进行性能优化,如果不优化会导致整个组件树重新渲染
    • vue:Object.defineProperty给模版数据添加getter setter进行数据劫持,数据更新即能触发watcher更新视图
  • 数据流动不同
    • react:单向数据流动,通过修改props state达到视图的更新
    • vue:双向数据绑定,v-model实现组件和DOM之间的双向绑定
  • 组件间通信不同
    • react:通过给子组件传递回调函数实现子向父传值
    • vue:通过自定义事件实现子组件向父组件传值
  • redux和vuex不一样
    • redux:数据不可变,每次state 的更新实际上是重新生成了一个state
    • vuex:数据可变,直接在原数据上进行修改
    • 具体内容:
      • 在 Vuex 中, s t o r e 被 直 接 注 入 到 了 组 件 实 例 中 , 因 此 可 以 比 较 灵 活 的 使 用 : 使 用 d i s p a t c h 和 c o m m i t 提 交 更 新 , 通 过 m a p S t a t e 或 者 直 接 通 过 t h i s . store 被直接注入到了组件实例中,因此可以比较灵活的使用:使用 dispatch 和 commit 提交更新,通过 mapState 或者直接通过 this. store使使dispatchcommitmapStatethis.store 来读取数据,组件中既可以 dispatch action 也可以 commit updates
      • 在redux中,每一个组件都需要显示的用 connect 把需要的 props 和 dispatch 连接起来,只能进行 dispatch,并不能直接调用 reducer 进行修改。
  • 数据变换的感知不同
    • Redux 在检测数据变化的时候,是通过 diff 的方式比较差异的,
    • 而Vuex其实和Vue的原理一样,是通过getter/setter来比较的(如果看Vuex源码会知道,其实他内部直接创建一个Vue实例用来跟踪数据变化)

react setState之后到底发生了什么?

如果这个问题现在让我回答的话,我会讲修改掉state中相应的值,从而会引起视图的更新。同时setState可以理解为异步的,state不会立即更新,所以我们可以在它的第二个参数那里写回调函数来获取更新后的state,实际上这完整吗?我们来看看下面的解释

当调用 setState 时,React会做的第一件事情是将传递给 setState 的对象合并到组件的当前状态。这将启动一个称为和解(reconciliation)的过程。和解(reconciliation)的最终目标是以最有效的方式,根据这个新的状态来更新UI。 为此,React将构建一个新的 React 元素树(您可以将其视为 UI 的对象表示)。

一旦有了这个树,为了弄清 UI 如何响应新的状态而改变,React 会将这个新树与上一个元素树相比较( diff )。

通过这样做, React 将会知道发生的确切变化,并且通过了解发生什么变化,只需在绝对必要的情况下进行更新即可最小化 UI 的占用空间。

以上这样答仍然显的很机械,下面进行整理。

  1. 传递给setState的对象和组件当前状态合并
  2. react创建一个新的元素树与旧的元素树diff
  3. 通过了解变化,在必要情况下进行更新

react中的keys和vue中的keys有区别吗?

我在vue中key的作用中做过总结,其实从说辞上看一个是react避免不必要的重新渲染,一个是vue让需要重新渲染的去重新渲染。

但在我看来其实本质上是一样的,key作为一个标识,应该是为了高效的更新虚拟DOM。

Vue2.0 v-for 中 :key 到底有什么用?
这篇文章的总结很好,也解开了我一直的疑惑:react和vue的diff算法到底是不是一样的?

答案是肯定有细微差别,但是核心的设计思路基本一致。核心基于两个假设如下:

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。

  2. 同一层级的一组节点,他们可以通过唯一的id进行区分。

react16的一些了解

更新于2019/08/30 目前对react16的了解并不是很多,尽管在前段时间做过的项目里就是用的react16,但事实上没有对一些新特性进行过使用,这部分内容会跟进更新。

references:

精读《React16 新特性》

生命周期钩子函数的更新

React16 采用了新的内核架构 Fiber,Fiber 将组件更新分为两个阶段:Render Parse 和 Commit Parse,因此 React 也引入了 getDerivedStateFromProps 、 getSnapshotBeforeUpdate 及 componentDidCatch 等三个全新的生命周期函数。同时也将 componentWillMount、componentWillReceiveProps 和 componentWillUpdate 标记为不安全的方法。

getDerivedStateFromProps(nextProps, prevState)

其作用是根据传递的 props 来更新 state。它的一大特点是无副作用,由于处在 Render Phase 阶段,所以在每次的更新都会触发该函数, 在 API 设计上采用了静态方法,使其无法访问实例、无法通过 ref 访问到 DOM 对象等,保证了该函数的纯粹高效。

为了配合未来的 React 异步渲染机制,React v16.4 对 getDerivedStateFromProps 做了一些改变, 使其不仅在 props 更新时会被调用,setState 时也会被触发。

  • 如果改变 props 的同时,有副作用的产生,这时应该使用 componentDidUpdate;
  • 如果想要根据 props 计算属性,应该考虑将结果 memoization 化;
  • 如果想要根据 props 变化来重置某些状态,应该考虑使用受控组件;
getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate(prevProps, prevState) 会在组件更新之前获取一个 snapshot,并可以将计算得的值或从 DOM 得到的信息传递到 componentDidUpdate(prevProps, prevState, snapshot) 函数的第三个参数,常常用于 scroll 位置定位等场景。

componentDidCatch(error, info)

componentDidCatch 函数让开发者可以自主处理错误信息,诸如错误展示,上报错误等,用户可以创建自己的 Error Boundary 来捕获错误。

为什么不安全?
componentWillMount(nextProps, nextState)

componentWillMount 被标记为不安全,因为在 componentWillMount 中获取异步数据或进行事件订阅等操作会产生一些问题,比如无法保证在 componentWillUnmount 中取消掉相应的事件订阅,或者导致多次重复获取异步数据等问题。

componentWillReceiveProps(nextProps) / componentWillUpdate(nextProps, nextState)

componentWillReceiveProps / componentWillUpdate 被标记为不安全,主要是因为操作 props 引起的 re-render 问题,并且对 DOM 的更新操作也可能导致重新渲染。

react-redux和vuex的区别

references:

Vuex与Redux对比

react-redux

  • 一个纯粹的状态管理系统,redux利用react-redux将它和React框架结合起来。
flux

Flux是为了解决在前端模块化开发后,组件之间的频繁数据交互导致的项目维护复杂的问题。

一般的组件传值,会在组件之间造成强关联,这种传值在项目比较小的时候还可控,
一旦项目变得庞大,将会导致整个项目逻辑变得十分复杂,数据交互变得冗长且不可控,
Flux应运而生。

Flux架构下,拆分成了View,Actions,Store三部分,
在View中的交互操作将会触发到actions,actions中对store进行改变,
当store进行改变后,相应的反过来去更新视图,这就是单向数据流。

单向数据流解决了组件相互传值不可控的问题,
所有数据的改变统一都流向了store。

redux

本身就是一个单纯的状态管理者,我们不追溯它的历史,从使用角度来说:它提供一个全局的对象store,store中包含state对象用以包含所有应用数据,并且store提供了一些reducer方法。这些方法可以自定义,使用调用者得以改变state的值。state的值仅为只读,如果需要更改则必须只能通过reducer。

react-redux

它提供了一些接口,如connect高阶组件,用于Redux的状态和React的组件展示结合起来,以用于实现状态与视图的一一对应

DVA

对React-Redux进行了封装,并结合了Redux-Saga(redux-saga是管理redux应用异步操作的中间件,通过创建sagas将所有的异步操作逻辑收集在一个地方集中处理select,call=>put,可以用来代替redux-thunk中间件,redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易。)等中间件,使用了model概念,也相当于在React-Redux的基础上针对web应用开发做了优化。

DVA数据流向图:
image

vuex

尤大也说过VUEX是吸收了Redux的经验,放弃了一些特性并做了一些优化,代价就是VUEX只能和VUE配合。

吸收了Redux的思想,并且针对web应用的开发模式和VUE框架做了优化。所以它在实现了全量Redux的思想以外,为了与VUE框架结合,它也具备了类似React-Redux中的与框架结合的功能(尽管具体使用方式可能有差异)

vuex数据流向图:
image

详细对比

redux vs vuex
Redux
  • 核心对象:store
  • 数据存储:state
  • 状态更新提交接口:dispatch
  • 状态更新提交参数:带type和payload的Action
  • 状态更新计算:reducer
  • 限制:reducer必须是纯函数,不支持异步
  • 特性:支持中间件
VUEX
  • 核心对象:store
  • 数据存储:state
  • 状态更新提交接口:commit
  • 状态更新提交参数:带type和payload的mutation提交对象/参数
  • 状态更新计算:mutation handler
  • 限制:mutation handler必须是非异步方法
  • 特性:支持带缓存的getter,用于获取state经过某些计算后的值
Redux vs VUEX 对比分析

store和state是最基本的概念,VUEX没有做出改变。其实VUEX对整个框架思想并没有任何改变,只是某些内容变化了名称或者叫法,通过改名,以图在一些细节概念上有所区分。

  • VUEX弱化了dispatch的存在感。VUEX认为状态变更的触发是一次“提交”而已,而调用方式则是框架提供一个提交的commit API接口。
  • VUEX取消了Redux中Action的概念。不同于Redux认为状态变更必须是由一次"行为"触发,VUEX仅仅认为在任何时候触发状态变化只需要进行mutation即可。Redux的Action必须是一个对象,而VUEX认为只要传递必要的参数即可,形式不做要求。
  • VUEX也弱化了Redux中的reducer的概念。reducer在计算机领域语义应该是"规约",在这里意思应该是根据旧的state和Action的传入参数,“规约"出新的state。在VUEX中,对应的是mutation,即"转变”,只是根据入参对旧state进行"转变"而已。
  • VUEX支持getter,运行中是带缓存的,算是对提升性能方面做了些优化工作,言外之意也是鼓励大家多使用getter。

总的来说,VUEX通过弱化概念,在任何东西都没做实质性削减的基础上,使得整套框架更易于理解了。

react-redux vs vuex
react-redux
  • 状态注入组件:组件结合connect方法
  • 容器组件:通过connect关联了state的组件,并被传入dispatch接口
  • 展示组件:不与state或dispatch直接产生关系
  • 特性:connect支持mapStatesToProps方法,用于自定义映射
VUEX
  • 状态注入组件:Vue.use(Vuex)将Vuex应用为全局的plugin,再将store对象传入根VUE实例
  • 容器组件:没有这个概念
  • 展示组件:在组件中可以获取this. s t o r e . s t a t e . ∗ , 也 进 行 t h i s . store.state.*,也进行this. store.state.this.store.commit()等等
  • 特性:VUEX提供mapState,mapGetter,mapMutation等方法,用于生成store内部属性对组件内部属性的映射
React-Redux vs VUEX 对比分析

通过使用方式上的较大差异,也可以看出理念上的不同。

  • 和组件结合方式的差异
    • VUE通过VUEX全局插件的使用,结合将store传入根实例的过程,就可以使得store对象在运行时存在于任何vue组件中。
    • React-Redux则除了需要在较外层组件结构中使用以拿到store之外,还需要显式指定容器组件,即用connect包装一下该组件。
  • 容器组件的差异
    • React-Redux提倡容器组件和表现组件分离的最佳实践
    • VUEX框架下不做区分,全都是表现(展示)组件。
dva vs vuex
DVA
  • 划分模块:提供了model的概念,一个model相当于是store的一个小块,DVA负责将这些小块整合成全局store而不需开发者关心。每个model提供配置namespace便于使用。
  • 异步方法调用:effect。由于包装了Redux-Saga,DVA支持将配置的effect方法做为model的一部分。每个effect方法是一个Generator函数,将异步方法(Promise)调用同步化,框架提供迭代器,执行时串行执行.通过包装,开发者可以通过dispatch调用Action,可以和调用reducer一样的方式调用effect方法。而effect内部提供API,用户获取参数、获取state、调用其他reducer等等。
VUEX
  • 划分模块:允许将store分割成module,概念与DVA中的类似。与DVA一样,它也提供访问自身state和全局state的方法,也提供通过namespace/module名的方式供组件使用的办法,也提供动态注册、模块重用等。
  • 异步方法调用:Action。Action类似于mutation,但是它内部支持异步调用。它无法直接更改state,但是可以使用context.commit()方式调用mutation。而对于开发者来说,不像DVA将effects和reducers的调用方式搞的相同,VUEX中的Action需要使用另一个API–dispatch接口来调用。它可以返回Promise对象,供调用者进行后续处理。
  • 特性:支持双向绑定
DVA vs VUEX 对比分析

它们将store拆分成模块的出发点是相同的,这也是大型应用开发所必备的。并且模块化的思路都是一样的。但是异步方法调用方面有所不同:

  • DVA更倾向于支持同步化的代码写法与执行方式。这样的好处是开发者使用effects和reducers时感觉是一样的。开发者可以适当规避使用Promise从而几乎不用接触异步概念,但是却需要接受Generator方法这种新事物。
  • VUEX倾向于将异步方法区分开。Action就是异步方法,而mutation就是非异步方法。声明方式、调用方式、入参等等,都是有明显区别的。这样的好处是时刻在提醒开发者需要将异步方法加以区分注意,并且可以很常规地使用Promise,使用异步特性。

VUEX还有个特性就是它的表单类组件的双向绑定。和VUEX结合之后,也是支持绑定到VUEX中的state上的。

VUEX的异步方法的提交方式,注意是“dispatch一个Action”。这在概念上是和Redux中的状态更新提交是一致的。从VUEX数据流向图也能看出,VUEX也是建议只向外部暴露Action供调用。这样一来,VUEX在使用上更加接近Redux了。

一些tips

  • 函数参数收集剩余参数的时候
function test(...args){
    // 此时args已经是一个数组了,可以直接用
    // 可以反向思考,相当于对一个数组解构变成了参数
}

函数副作用

函数副作用是指当调用函数时,除了返回函数值之外,还对主调用函数产生附加的影响。副作用的函数不仅仅只是返回了一个值,而且还做了其他的事情,比如:

  1. 修改了一个变量
  2. 直接修改数据结构
  3. 设置一个对象的成员
  4. 抛出一个异常或以一个错误终止
  5. 打印到终端或读取用户输入
  6. 读取或写入一个文件
  7. 在屏幕上画图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值