《React基础》

372 阅读3分钟

如何引入React

1. bootcdn

从bootcdn上下载,但是这样做很麻烦,通常不使用。

2. create-react-app

(和vue cli类似)

安装

yarn global add create-react-app

使用它创建项目

cd /d/jirengu   先进入项目所在的目录
create-react-app react-demo-1

创建成功后,会自动出现提示接下来的代码:

进入创建的项目目录,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="./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="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。

DOM Diff算法 React会对比两个虚拟DOM的不同,只局部更新视图。只更新不同的地方。