Vue 转 React指北

Vue 转 React 指北

一. 运行时性能

React 应用中,当某个组件的状态发生变化时,它会以该组件为根,无论其子树是否依赖更新后的 props,都会重新渲染整个组件子树。

为了避免不必要的子组件渲染,可以使用 PureComponent,或手动在需要的地方设置 sholdComponentUpdate 钩子。

但是使用 PureComponentshouldComponentUpdate 时,需要保证该组件整个子树的渲染输出都是由该组件的 props 决定的。不然此类优化又会导致难以察觉的问题(渲染结果不一致)。

在 Vue 应用中,组件依赖是在渲染过程中自动追踪的,系统能精确知道那个组件被重新渲染。你可以理解为每一个组件都已经自动获得了 shouldComponentUpdate,并且没有上述的子树问题限制。

二. 数据流

Vue

双向绑定,单向数据流:vue2.x 通过 v-model 实现双向绑定,可以不关心受控组件,v-model 相当于 onChange 的语法糖

1
<input v-model="value" />

React

单向数据流:万物皆 Props,主要通过 onChange/setState()的形式该更新数据,需要所以在 react 中需要关注受控组件的写法

1
2
3
4
5
// 会报错,props的值不可修改
<input value="{this.props.value}" />

// 在onChange调用setState修改数据,需要调用setState修改绑定数据
<input value="{this.state.value}" onChange="{this.onChange}" />

受控组件

在 HTML 中,标签<input><textarea><select>的值的改变通常是根据用户输入进行更新。在 React 中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的 React 组件也控制着在后续用户输入时该表单中发生的情况,以这种由 React 控制的输入表单元素而改变其值的方式,称为:“受控组件”。绑定了 onChange,随着 state 更新而更新的 input 组件(的 value)就是受控组件。


非受控组件

表单数据由 DOM 本身处理。即不受setState()的控制,与传统的 HTML 表单输入相似,input 输入值即显示最新值(使用 ref从 DOM 获取表单值)

如图:

三. 组件

1、组件封装

Vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 父组件
<template>
<div class="father">
父组件
<Child :text="text"></Child>
</div>
</template>
<script>
import Child from "./Child";
export default {
name: "Father",
components: {
Child,
},
data() {
return {
text: "接收到了父组件数据",
};
},
};
</script>

// 子组件
<template>
<div class="child">
<p>{{ text }}</p>
<p>{{ children }}</p>
</div>
</template>

<script>
export default {
name: "child",
props: ["text"],
data() {
return {
children: "子组件自己的数据",
};
},
};
</script>

React

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import React, { useState, useEffect } from "react";

function Child({ onClick }) {
const [list, setList] = useState<number[]>([]);
useEffect(() => {
setList([1, 2, 3]);
}, [onClick]);

return (
<div>
{list.map((item, index) => {
return <div key={index}>{item}</div>;
})}
</div>
);
}

function Father() {
const show = () => {
return [4, 5, 6];
};

return (
<div>
<Child onClick={show}></Child>
</div>
);
}

export default Father;

2、组件通信

Vue
  • props/emit
  • provide/inject
  • vuex(双向数据绑定,响应式)
  • event bus
React
  • props(子传父通过props.function)
  • context
  • redux(单向数据流)

3、组件嵌套

Vue:slot 插槽
1
2
3
4
5
6
7
8
9
10
11
12
13
// index.vue
<template>
<Test>
<div>插槽文本</div>
</Test>
</template>
; import Test from "./test"; // test.vue
<template>
<div>
<slot></slot>
</div>
</template>
;
React: props.children
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 父组件
import Test from "./test";

<Test>
<div> 组件嵌套 </div>
</Test>;

// 子组件
import * as React from "react";

const Test: React.FC<any> = (props) => {
return (
<>
<div>测试props.children</div>
<div>{props.children}</div>
</>
);
};

export default Test;

四.总结

1、一些区别

  • vue 更简单,更方便,熟悉了 api 以后,实现某些简单功能更快。react 写法更偏向于原生 JS,Class 的写法不是很舒服,个人更喜欢 hooks
  • 熟悉了 hooks 以后,写起来很自由,不用关心 vue 中固定的 options api
  • react 做中后台优势更大,有大厂加持,生态更好,组件库功能也更多,解决方案也更多
  • vue2.x 对 typescript 不太友好,react + typescript 更加舒适,两者写起来风格差距较大。
  • react JSX 写起来还是不够熟练,onClick、style、className 等等,没有 v-if,v-for,All in JS。Vue 则推崇 html、js、css 分离的写法,当然 vue 也可以写 JSX
  • vue 的 prop 必须在子组件 props 字段里声明。React 的 prop 不强制声明,直接使用,如果用 TS 的话还是要声明的

2、学习

  • 很多人说 vue 转 react 很简单,一周熟练上手。我比较菜,感觉适应起来还是有成本的,但是也没有很难,最主要的还是要多动手,不懂就深挖为什么
  • 通读一遍 react 官网,对着例子多敲敲,好好理解,做做笔记。
  • B 站 React 技术全家桶 学习视频,可以不敲,快速过一遍,毕竟都不是小白了。然后自己搞个项目,去实现一些自己感兴趣的东西
  • 基础知识过完以后,查缺补漏,找各种博文读一读,不理解的再次进行学习
  • 总结自己的学习成果,react 已经学了一段时间了,后面再整理一下,发出来
  • 为了提高熟练度,用公司的组件库(zent)自己动手写了写,有兴趣的老哥参考下:在线预览:俊劫学习系统 Github 源码:基于 react + typescript 欢迎start

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!