壹 ❀ 引

按照之前的计划,从这个月开始,我将由浅至深更新一些react相关的技术博文。由于我目前也是react新手一名,所以文章本质上也算自己学习历程的记录,倘若这些文章能帮助到一些人那就再好不过了。那么这一篇文章就作为一个新的开端,从零开始一起变得更强吧,本文开始。

贰 ❀ 准备工作

在学习基础知识之前,我们可以在本地搭建并运行一个react应用,便于后续学习时例子效果预览。请先确保电脑已成功安装node.js。

比如我的学习项目都喜欢丢在D盘,所以可以在D盘新建一个job文件夹(名字随你喜欢),进入job目录,打开终端,这里我用的git终端。执行复制npx create-react-app my-app命令并回车,等待安装完成。

等到出现Happy hacking!,说明下载完成。

之后就可以看到job目录下多了一个my-app文件夹,这就是我们下载的react应用了。双击进入my-app目录,再进入src文件夹,删除所有文件之后,创建index.css与index.js文件,像这样:

用编辑器(我用的vscode)打开my-app项目,在前面创建的index.js中拷贝如下代码:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css"; ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById("root"));

注意,由于react的jsx语法特性,我们可以在js中编写html,所以习惯格式化代码的同学可能会将代码格式出问题,毕竟js中无法识别HTML。对于这个问题我们可以通过切换编辑器语言模式来解决,点击编辑器右下角的语言,如下图:

输入java可以看到下方有个javaScript React,选择此语言,再格式化你就发现支持jsx语法了。

每次点击右下角切换语言也比较麻烦,好的做法是给选择语言模式直接配置一个键盘快捷方式。点击编辑器左上角的文件--->首选项--->键盘快捷方式,之后输入语言,可以看到有一个更改语言模式。点击左边的修改图标,输入你想要的快捷方式,保存即可,这里我用快捷键是ctrl+k,之后就可以通过快捷键快速切换语言模式了。

ok,简单说了下语言模式的事情,现在我们可以通过ctrl+~打开编辑器的终端,然后输入npm start并回车。

你会发现浏览器自动打开了一个页面,这就是我们本地开发环境成功跑起来了。使用本地环境的好处是,我们每次修改并保存代码,页面都会自动刷新,而此时页面赫然显示了一句 Hello, world!,恭喜你,到这里我们成功创建了第一个属于自己的应用,虽然它目前还很简单,但通过后面的学习,我们来一起让它变得更酷!

叁 ❀ jsx基础

按照以往传统的开发习惯,dom结构我们一般写在html中,而js文件会负责业务相关逻辑,但站在react的角度,我们会在js中编写html相关代码,如果你有了解vue的jsx语法,我想你会更快接受这一设定,之前没了解也不用担心,我们来解释下文章开头代码做了什么。

让我们打开项目的public文件,查看index.html,可以看到代码中有一个id为root的div盒子,结合我们前面例子中ReactDOM.render编译的内容,其实不难理解,render只是将需要编译的dom,塞到了root的盒子中,这种指定应用容器以及编译内容的思想其实与vue以及angularjs是相似的,只是现在html换了个地方编写而已。

jsx属于JavaScript的语法拓展,事实上它既不是标签语法,也不是普通字符串(官方称呼react元素),但它具备JavaScript全部功能。我们编写的jsx其实会被bable转译成React.createElement()调用(vue也有类似的createElement方法),比如下面这段代码是等效的:

const ele = <h1 className="echo">Hello, world!</h1>;
// 等同于
const ele = React.createElement(
"h1", //标签名
{ className: "echo" }, //标签属性
"Hello, world!" //子节点内容
);

而React.createElement()本质上是创建了一个类似于如下的React对象,react会读取并编译这些对象,用它们构建页面dom并实时保持更新:

const ele = {
type: 'h1',
props: {
className: 'echo',
children: 'Hello, world!'
}
};

当然这里我们先不用了解的太深,只用知道jsx大致做了什么,以及为什么react中能这么写就足够了,它们的转换过程其实是react元素经过bable转译--->React.createElement()调用--->react对象--->真实dom。而接下来的语法介绍我想大家会十分熟悉。

react元素支持赋予给变量,比如文章开头的例子也可以写成这样:

const ele = <h1>Hello, world!</h1>;
ReactDOM.render(ele, document.getElementById("root"));

当然,react元素支持嵌套,但需要注意的是,如果我们的结构需要换行,官方推荐使用圆括号包裹你的结构,比如:

const ele = (
<div>
<h1>Hello World!</h1>
<h1>My name's echo!</h1>
</div>
);
ReactDOM.render(ele, document.getElementById("root"));

这样做的好处是能避免代码压缩遇到自动插入分号的陷阱。

在vue开发中,我们习惯使用模板语法{{}}解析变量,表达式,调用方法等等,其实在react中你同样能这么做,比如:

const myName = "echo";
const add = function (a, b) {
return a + b;
}; const ele = (
<div>
<h1>my name is {myName}</h1>
<h1>{add(2, 2)}</h1>
<h1>{2 + 2}</h1>
</div>
);
ReactDOM.render(ele, document.getElementById("root"));

html标签有属性,react元素与标签一样,同样也支持标签属性以及自定义,比如下面的例子:

const img = "https://pic.cnblogs.com/avatar/1213309/20200507225901.png";
const ele = (
<div>
<div id="icon">头像</div>
<img src={img} alt="icon" />
</div>
);
ReactDOM.render(ele, document.getElementById("root"));

这里需要注意的是,不要在{}外添加引号,如果你需要解析变量,请使用{},如果它只是一个字符串,那么请添加引号,二者选其一添加,两者不要同时使用。

最后,当添加一个jsx结构时只能有一个react根元素,这点与angularjs的自定义指令模板,vue的组件只能有一个根元素情况类似,比如下面这段代码就是错误示范:

const ele = (
<div>1</div>
<div>2</div>
);

正确的做法是为这两个元素添加一个共有的根元素:

const ele = (
<div>
<div>1</div>
<div>2</div>
</div>
);

但请不要将这些jsx的结构理解成react组件,它们只是一些react元素构成的代码块,组件会有专门的方式去创建,这个后面会具体介绍,当然组件也会利用react元素来构建必要的dom结构。

肆 ❀ 元素渲染的不变性

按照我们以往的框架使用经验,当模板语法解析的某个变量发生改变时,页面会自动更新这个变量。但在react中,元素渲染都是一次性的,渲染成功后修改变量,页面并不会有改变,请看下面这个例子:

let num = 0;
setInterval(function () {
num++;
}, 1000); setInterval(function () {
//控制台输出num
console.log(num);
}, 1000); const ele = <div>{num}</div>;
ReactDOM.render(ele, document.getElementById("root"));

打开控制台,你会发现num在不断自增,而页面结构中解析的num依旧是0,并没有任何变化,这是因为ReactDOM.render就是一次性执行,它只会调用了一次,因此没办法及时更新num,比较直接的办法是可以将render整个过程也包裹在定时器中,比如:

let num = 0;
setInterval(function () {
num++;
}, 1000); setInterval(function () {
//利用定时器不断更新react元素,以及让render重复渲染
const ele = <div>{num}</div>;
ReactDOM.render(ele, document.getElementById("root"));
}, 1000);

这样做能达到效果,但直观感受这种做法并不友好,其实在后续文档中,react有提供状态专门用于解决这个问题,当然这都是后话了。

其次,我们虽然用定时器反复执行render,但神奇的是react在每次更新dom时,对比新旧dom结构,并只更新发生变化的部分,打开浏览器控制台,观察dom变化就非常清楚了。这一点相对我之前使用的angularjs,就非常人性化了...

伍 ❀ 总

那么到这里,我们成功在本地搭建了一个属于自己的应用,并了解了react中jsx语法,以及一些常见的用法。学习完这些内容,我们可以利用react元素构建出一些简单的静态页面,虽然现在还未涉及组件概念,当然这些将会在后续文章中展开。

不知不觉又凌晨一点了,这篇文章就先写到这里,那么本文结束。

从零开始的react入门教程(一),让我们从hello world开始的更多相关文章

  1. react 入门教程 阮一峰老师真的是榜样

    -  转自阮一峰老师博客 React 入门实例教程   作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Nati ...

  2. React入门教程(二)

    前言 距离上次我写 React 入门教程已经快2个月了,年头年尾总是比较忙哈,在React 入门教程(一)我大概介绍了 React 的使用和一些注意事项,这次让我们来继续学习 React 一. Rea ...

  3. React入门教程1---初见面

    React入门教程1---初见面:https://blog.csdn.net/solar_lan/article/details/82799248 React 教程 React 是一个用于构建用户界面 ...

  4. 160921、React入门教程第一课--从零开始构建项目

    工欲善其事必先利其器,现在的node环境下,有太多好用的工具能够帮助我们更好的开发和维护管理项目. 我本人不建议什么功能都自己写,我比较喜欢代码复用.只要能找到npm包来实现的功能,坚决不自己敲代码. ...

  5. 25、react入门教程

    0. React介绍 0.1 什么是React? React(有时称为React.js 或ReactJS)是一个为数据提供渲染HTML视图的开源JavaScript库. 它由FaceBook.Inst ...

  6. React 入门教程

    React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...

  7. React入门教程

    做前端的人都知道,目前热门前端的框架是 VAR => Vue,Anglur,React. 而如果说最热门的前端框架是谁,毫无悬念是 React React 是由 Facebook 主导开发的一个 ...

  8. 前端三大框架之一React入门教程

    相信大家对框架这个词都很熟悉吧,我一直喜欢js原生来开发,但是目前都要求工作效率,所有使用框架或者是库会使我们开发更加方便和快速,甚至一个人干十个人的活.. 框架优点: 1.方便开发.快速写功能 2. ...

  9. React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

  10. 2015年最热门前端框架React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

随机推荐

  1. java项目实践-cookie-session-day18

    目录 1. cookie 2. session 3. servletcontext 4.servletConfig 1. cookie cookie 在客户端(浏览器)中保持http状态的 信息技术 ...

  2. Go image registry

    0. 前言 OpenShift image registry 概述 介绍了 OpenShift 平台上 registry 的基本结构.进一步地,本文将介绍在 Kubernetes 平台上,如何使用 G ...

  3. NewStarCTF 2023 公开赛道 WEEK3|CRYPTO WP

    一.Rabin's RSA 题目信息 from Crypto.Util.number import * from secret import flag p = getPrime(64) q = get ...

  4. 【js】 Object.prototype.toString.call()

    1,Object.prototype.toString这个方法的作用是什么  判断数据类型 2,为什么要用这个方法 是因为  js 中 一般的类型判断 对于 null,数组,对象 , 都会返回一样的结 ...

  5. SQLServer解决deadlock问题的一个场景

    SQLServer解决deadlock问题的一个场景 背景 公司产品出现过很多次dead lock 跟研发讨论了很久, 都没有具体的解决思路 但是这边知道了一个SQLServer数据库上面计划100% ...

  6. [转帖]Linux内核参数 rp_filter

    https://www.cnblogs.com/chenmh/p/6001977.html 简介 rp_filter (Reverse Path Filtering)参数定义了网卡对接收到的数据包进行 ...

  7. [转帖]VMware Converter (P2V迁移)问题汇总

    https://www.dinghui.org/vmware-converter-p2v.html VMware vCenter Converter Standalone,是一种用于将虚拟机和物理机转 ...

  8. [转帖]一文浅析Nginx线程池!

    https://zhuanlan.zhihu.com/p/616500765     Nginx通过使用多路复用IO(如Linux的epoll.FreeBSD的kqueue等)技术很好的解决了c10k ...

  9. [转帖]UseG1GC垃圾回收技术解析

    https://www.cnblogs.com/yuanzipeng/p/13374690.html 介绍 G1 GC,全称Garbage-First Garbage Collector,通过-XX: ...

  10. es6 Array.form将类数组或者对象转化为数组

    Array.from()方法就是将一个[类数组对象][或者可遍历对象]转换成一个[真正的数组] 那么什么是类数组对象呢?所谓类数组对象,最基本的要求就是具有length属性的对象. let array ...