Talk is cheap. Show me your code

从 Vue 的视角学 React(二)—— 基本语法

基于 Vue.js 开发的时候,每个 vue 文件都是一个单独的组件,可以包含 HTML,JS,CSS

而 React 是以函数为基础,每个 function 就是一个组件。虽然 JSX 让 HTML 的写法更加友好,但 CSS 还是需要另外引入

Vue 还给开发者提供了很多指令,而 React 中并没有,所以这片文章会介绍两者之间的常用语法差异

 

 

一、私有化 CSS

在 vue 文件中,可以直接通过 <style> 标签来写 CSS 样式

如果希望这些 CSS 仅对当前的 vue 文件生效,只需要在 <style> 标签中添加 scoped 属性

由于 React 是以 JSX 语法来编写代码,可以写行内样式,但不能添加 <style> 标签,所以通常是单独写一个 css 文件,然后直接在 JSX 中引入

// 需要提前安装 css-loader

 

但这种直接引入的 CSS 是全局生效的,如果只是针对当前组件的 CSS,可以通过 CSS Modules 来实现

将 CSS 文件重命名,添加一个 module 中间名,并且作为一个对象引入

然后以变量的形式添加 className。如果继续用之前字符串的形式引入,样式并不会生效

需要注意的是,由于 className 是以变量属性的方式引入,不支持短线连接,建议改为驼峰命名

这样一来,CSS 经过编译之后,每一个类都会生成一个哈希值,使这个类全局唯一,从而实现样式私有化

 

 

二、双向绑定

Vue 的特性之一就是双向绑定,而 React 是单向数据流直接修改属性无法即时渲染到页面

需要在构造函数里面添加 state 状态

这里的 super() 是 ES6 提供的关键字,用于调用父类中的构造函数

React 中每一个需要用到 props 和 state 的组件都需要 super(props)

以便 React.Component 的构造函数可以初始化 this.props


如果需要修改 state 中的属性,需要使用 setState() 

 

 

三、循环渲染

开发的时候经常会有基于数组渲染列表的需求,Vue 提供了 v-for 指令,而 JSX 中就需要借助数组的 map 函数

假设在 state 中定义了这么一个数组:

如果需要基于这个数组渲染一个列表,可以在 render() 函数中定义一个对象,用于循环渲染数组,最后将这个对象放到合适的位置

这里更好的做法是在 render() 之外创建一个函数,封装具体的遍历逻辑,然后返回一段 JSX

需要注意的是,和 Vue 的 v-for 指令类似,在使用 map 函数的时候,也需要给 DOM 节点添加一个 key

 

 

四、条件渲染

通过上面的代码可以看出,React 没有像 Vue 提供各种各样的语法糖,但所有需求都可以通过 JavaScript 本身语法来实现

所以 React 并不需要 v-if 这样的条件判断指令,直接用 if...else... 就能实现条件渲染

如果需要根据条件隐藏组件,只要让对应的函数返回 null 即可

 

 

五、DOM 操作

主流的前端框架都在倡导数据驱动,不过在实际业务中难免会有需要操作 DOM 的时候

在 Vue 项目中,可以通过 ref 为组件添加唯一 ID,从而获取到该组件实例,其中就包含了该组件的 DOM 对象

React 也有 ref 属性,功能和 Vue 中的 ref 相仿,不过具体的使用有些差异

首先需要通过 React.createRef() 构造函数中创建一个 ref 对象

然后将这个对象挂到 render() 中的 DOM 元素或 class 组件

另外还可以通过 React.forwardRef() 来转发 ref,通常在包装组件、开发高阶组件的时候会用到

主要用来透传某些 props,具体的使用可以参考官方文档

 

虽然 Vue 和 React 都提供了 ref,但官方并不推荐频繁使用

项目中用到 ref 的时候,更多的是用来处理一些特殊需求,比如获取 DOM 元素的坐标

如果需要用到 ref 来做数据处理或者页面渲染,通常也能通过 props、state、事件上报、状态提升等办法来实现同样的功能 

在开发项目的时候,如果能花更多的时间来思考设计方案,而不是解决某个功能点,对项目、对个人都是非常有益的

 

 

参考资料:

《React 中使用CSS》

《谈谈JavaScript中super(props)的重要性》

posted @ 2019-05-28 15:05  Wise.Wrong  阅读(1297)  评论(0编辑  收藏  举报