如何引入React
从CDN引入React
一般不使用这种方法
通过webpack引入React(老手使用)
import ... from ...
//cmder
yarn add react react-dom
//js
import React from 'react'
import ReactDOM from 'react-dom'
//注意大小写
//除webpack外,rollup、parcel也支持上面写法
复制代码
一般不使用这种方法,需要自己配webpack/rollup(老手使用)
通过create-react-app引入React(新手使用)
(和vue cli类似)
- 安装
yarn global add create-react-app
复制代码
- 使用它创建项目
cd /d/jirengu //先进入项目所在的目录
create-react-app xxx //xxx是项目名
复制代码
创建成功后,会自动出现提示接下来的代码:
进入创建的项目目录,yarn start 开启服务器。会开启一个3000端口
在window上终端输入 start . ,打开当前目录,就是上一个cd的项目目录,然后把该项目手动拖进vscode。
原生JS体验React
在codesandbox上创建一个原生JS项目,先只保留html,js,css
//index.html
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://juejin.cn/post/src/index.css" />
</head>
<body>
<div id="root"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.development.min.js"></script>
<script src="https://juejin.cn/post/src/index.js"></script>
</body>
</html>
复制代码
有一个空的div,作为容器。bootcdn引入React
和ReactDOM(优先umd)
,引入js。
想在页面展示一个n 和+1按钮
//index.js
let n = 0;
const root = document.querySelector("#root");
const React = window.React;
const ReactDOM = window.ReactDOM;
const App = React.createElement("div", { className: "red" }, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
ReactDOM.render(App, root);
}
},
"+1"
)
]);
ReactDOM.render(App, root);
复制代码
用React创建视图,一个div
,用ReactDOM把这个节点插入页面。
这个div元素有一个red class
,里边的内容有一个n,和一个Button
元素。button
也是用React创建的,它的内容是+1
字符串,点击,把n+1,然后再次渲染App。
但是发现点击按钮,页面里的n没有加1.因为React并不会像Vue那样监听和劫持数据。而且,创建App的时候,div的内容n在那一瞬间就已经是0了,之后再对n进行改变,都不会影响这个0。
那怎么做到让这个App再取一次值呢?一个简单的方法就是把App赋值改成函数。
const App = ()=>React.createElement("div", { className: "red" }, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
ReactDOM.render(App(), root);
}
},
"+1"
)
]);
ReactDOM.render(App(), root);
复制代码
改成函数,就意味着渲染的时候,要调用函数,它的返回值是创建的一个节点,每次调用就会执行一次,也就会再次重新取值,页面上展示的就会是n的值,而不是一开始就取好的0
函数的本质-延迟
普通代码与函数的区别
普通代码
let b=a+1
复制代码
函数(不讨论参数)
let f=()=>a+1
let b=f()
复制代码
普通代码会立即执行,也就是立即取值,当前a是什么,就取那个值。
函数相当于把语句包起来了。在定义的时候不会求值。只有在调用的时候,才会去求值。即延迟求值。所以如果a的值变了,调用函数的时候取的值是a的最新值。
而普通代码在一开始赋值的时候,就固定了。之后a的值再变,也和b无关。
React元素和React函数组件
也是一个道理。
const App1 = React.createElement("div", null,n)
复制代码
App1是一个React元素,它所要展示的n在这句代码执行结束的一瞬间,就固定了,立即取值。之后改变n,展示的值也不会再变了。
const App2 = ()=> React.createElement("div", null,n)
复制代码
App2是一个React函数组件。他是一个函数。在定义的时候,没人关心它里边的变量取什么值。只有在调用的时候,App2() ,才会去取值,即延迟取值。所以采用函数的写法,就可以在调用的时候,拿到n的最新值。
函数是延迟执行的代码,注意这里的延迟指的是代码执行的时机,并不是同步异步。同步异步关注的是得到结果的时机。
小结
目前我们知道了两个概念:
React元素:React.createElement()
返回一个element,可以代表一个div
但是这个element并不是真正的div元素,也不是DOM对象(不能把它直接插入页面中)。通常我们把它叫做虚拟DOM对象。
React函数组件:()=>React
元素 ,这个函数的返回值是一个element,也可以代表一个div。并且,这个函数可以多次执行,每次都会得到最新的element。
React会对比两个虚拟DOM的不同,只局部更新视图。只更新不同的地方。
找不同的算法叫DOM Diff算法