React入门学习

通过 npm 使用 React

首先需要安装Node.js
建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack,我在项目使用 webpack

第一步. 安装全局包

参数-g表示我们将全局(global)安装 webpack, 这样你就能使用 webpack 命令

//安装ES6转码器babel
$ npm install babel -g
//全局安装webpack
$ npm install webpack -g
//安装webpack的web服务器webpack-dev-server
$ npm install webpack-dev-server -g

第二步. 创建根目录

创建一个根目录,目录名为:webApp,然后使用 npm init 初始化,生成 package.json 文件:

$ mkdir webApp
$ cd webApp/
$ npm init
name: (webApp) webapp
version: (1.0.0) 
description: 我的 react 测试
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to E:/webapp/package.json:

{
  "name": "webapp",
  "version": "1.0.0",
  "description": "我的 react 测试",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "liujie",
  "license": "ISC"
}


Is this ok? (yes)

第三步. 添加依赖包及插件

因为我们要使用 React, 所以我们需要先安装它,–save 命令用于将包添加至 package.json 文件

$ npm install react --save
$ npm install react-dom --save

同时我们也要安装一些 babel 插件:

$ npm install babel-core --save
$ npm install babel-loader --save
$ npm install babel-preset-react --save
$ npm install babel-preset-es2015 --save

devDependencies和dependencies的区别:

"dependencies": {},//生产环境
"devDependencies": {}//开发环境

特别说明:
devDependencies 里面的插件只用于开发环境,不用于生产环境,而 dependencies 是需要发布到生产环境的。
使用 --save-dev 安装的插件,被写入到 devDependencies 对象里面去,而使用 --save安装的插件,则被写入到 dependencies对象里面去。
区别:
--save-dev--save的区别:我们可以先简单的理解为打包工具和测试工具用到的包使用 --save-dev存到 devDependencies , 比如eslint, webpack. 浏览器中执行的js用到的包存到 dependencies, 比如jQuery等。
测试说明:
删除node_modules目录;
然后执行 npm install --production,可以看到,npm只帮我们自动安装package.json中dependencies部分的模块;
如果执行npm install,则package.json中指定的dependencies和devDependencies都会被自动安装进来。

.gitignore文件作用

因为有些npm包安装是需要编译的,那么导致windows/mac/linux上编译出的二进制是不同的, 也就是无法通用。因此我们在提交代码到git上去的时候, 一般都会在 .gitignore 里指定忽略node_modules目录和里面的文件,
这样其他人从git上拉下来的项目是没有node_modules目录的, 这时我们需要运行

$ npm install

它会读取 package.json 中的 devDependenciesdependencies字段, 把记录的包的相应版本下载下来。


第四步.创建文件

接下来创建项目的一些必要文件:

$ touch index.html
$ touch App.jsx
$ touch ceshi.js
$ touch webpack.config.js

第五步. webpack.config.js配置

其实就是设置编译器,服务器,载入器

var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
var config = {
     //插件项
      plugins:[commonsPlugin],
     //页面入口文件配置
     entry: {
         index:'./ceshi.js'
     },
    //入口文件输出配置
    //output:是指页面通过webpack打包后生成的目标文件放在什么地方去,我这边是在当前目录下的js文件夹
     output:{
         path:'./js',
         filename: '[name].bundle.js'
     },
    devServer: {
      inline: true,
      port: 8888
   },
     module: {
         //加载器配置
         //当加载的文件匹配相应的test正则时,才会调用相应的loader对文件进行处理
        loaders:[
         {
            test: /\.css$/,
            loader: 'style-loader!css-loader'
        },
         {
               test: /\.(png|jpg)$/,
               loader: 'url-loader?limit=8192'
         },
         {
             test: /\.js$/, 
             loader: 'babel-loader', 
             query:{
             presets:['es2015','react']
             }
         },
         {
             test: /\.jsx$/, 
             loader: 'babel-loader!jsx-loader?harmony'
         }
         ]
     },
     resolve: { extensions: ['', '.js', '.jsx'] }
 }
 module.exports = config;
  • entry: 指定打包的入口文件 ceshi.js。
  • output:配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称。
  • devServer:设置服务器端口号为 8888,端口后你可以自己设定 。
  • module:定义了对模块的处理逻辑,这里可以用loaders定义了一系列的加载器,以及一些正则。当需要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的原因。

现在打开 package.json 文件,找到 “scripts” 中的 “test”:”echo \”Error: no test specified\” && exit 1” 使用以下代码替换:

"start": "webpack-dev-server --hot",
"build": "webpack"

现在执行 npm build 相当于 webpack, npm start 相当于 webpack-dev-server –hot. 当项目变得相当复杂时, 你可以使用这种技巧隐藏其中的细节.
替换后的 package.json 文件 内容如下:

{
  "name": "webapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot",
    "build": "webpack"
  },
  "author": "liujie",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^1.12.15",
    "webpack-dev-server": "^1.14.1"
  },
  "dependencies": {
    "babel-core": "^6.7.6",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "react": "^15.0.1",
    "react-dom": "^15.0.1"
  }
}

现在我们可以使用 npm start 命令来启动服务。–hot 命令会在文件变化后重新载入,这样我们就不需要在代码修改后重新刷新浏览器就能看到变化。

第六步. 编写相应文件

index.html
设置 div id = “app” 为我们应用的根元素,并引入 index.bundle.js 脚本文件。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>测试</title>
</head>
<body>
    <div id="app"></div>
    <script type="text/javascript" src="js/common.js"></script>
    <script type="text/javascript" src="js/index.bundle.js"></script>
</body>
</html>

App.jsx
这是一个 react 组件

import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component{
    render(){
        return (
        <div>
        <h1>这是我的第一个react程序</h1>
        </div>
            );
    }
} 
//导出默认的类
export default App;

ceshi.js
我们需要引入组件并将其渲染到根元素 App 上,这样我们才可以在浏览器上看到它

import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App";

ReactDOM.render(<App/>,document.getElementById("app"));

注意:
如果想要组件可以在任何的应用中使用,需要在创建后使用 export 将其导出,在使用组件的文件使用 import 将其导入

第七步. 运行服务

完成以上配置后,我们即可运行该服务:

$ npm start

通过浏览器访问 http://localhost:8888/,输出结果如下:
结果图片

虚拟DOM

浏览器渲染页面的一般过程通常是这样的:
加载html文档->生成DOM树->解析css生成Render树->生成页面
那么React的virtual dom是怎么做的呢?
生成virtual dom->diff->必要的DOM更新

虚拟DOM能带来什么样的好处?这需要从浏览器本身说起。正如我们所知道的,在浏览器渲染网页的过程中,会将HTML文档解析并构建DOM树,然后将其与解析CSS生成的CSSDOM树一起结合生成——Render树(渲染树),然后将Render树渲染成页面。
这些过程都存在与渲染引擎之中,渲染引擎在浏览器中是和JavaScript引擎(JavaScriptCore也好V8也好)分离开的,但为了方便JS操作DOM结构,渲染引擎会暴露一些接口供JavaScript调用。由于这两块相互分离,通信是需要付出代价的,因此最佳实践在于尽可能的减少DOM的操作次数。

而虚拟DOM干了什么?它直接通过JavaScript实现了DOM树。组件的HTML结构并不会直接生成DOM,而是映射生成虚拟的JavaScript DOM结构,React又通过在这个虚拟DOM上实现了一个 diff 算法找出最小变更,再把这些变更写入实际的DOM中。这个虚拟DOM以JS结构的形式存在,计算性能会比较好,而且由于减少了实际DOM操作次数,性能会有较大提升。
dom-diff是指: 所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上。它可以极大提高网页的性能表现。
除了性能的考虑,React引入虚拟DOM更重要的意义是提供了一种一致的开发方式来开发服务端应用、Web应用和手机端应用:即实现多端同构。
这里写图片描述
因为有了虚拟DOM这一层,所以通过配备不同的渲染器,就可以将虚拟DOM的内容渲染到不同的平台。而应用开发者,使用JavaScript就可以通吃各个平台了。

react 组件key的问题

在做项目的过程中出现了这样的提示信息:

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method

使用diff算法时:根据key决定是否重新渲染,在key唯一的情况下,如果一个组件没有任何变动的时候,重新render父组件,该组件是不会再次render的。
说白了,react的key关乎到react的dom-diff算法,react中对于dom的操作是根据生成的data-reactid进行绑定的,添加key可以保证dom结构的完整性,而不会根据react自己对dom标记的key进行重新分配。react每次决定重新渲染的时候,几乎完全是根据data-reactid来决定的,最重要的是这个机制。
这个key应该是data-reactid有关系,这个data-reactid是react自动生成为dom-diff算法服务的,你打开react生成的html里面能看得见。添加key应该是保证react-vdom的标识唯一性,你应该发现只有添加一批完全一样的component在同一节点下才会有这个warning。
react的diff算法,每次render的时候都会根据这个唯一标记的dom来决定是否要重新渲染这部分,以此来达到减少不需要的dom操作,提高性能的目的。你可以试一下,react的组件在update的时候性能明显好于其他框架。
你添加了一些你认为唯一性的数据但是没起到作用,很可能是数据在你不知道的地方有重复的原因,想省事就放个index肯定可以去掉warning。

如果不添加 key,react会提示warning而已,并不会报错。如果报错了,肯定是代码哪里有问题。 warning不是报错。可以忽略的。
但是不加key会影响react渲染的性能,如果这样做diff算法就不起作用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值