引入React
1、从 CDN 引入
CDN 引入比较麻烦,注意以下顺序:
<script src="https://.../react.xxx.min.js"></script>
<script src="https://.../react-dom.xxx.min.js"></script>
- 引入 React
- 引入 ReactDOM
cjs 版和 umd 版的区别:
- cjs 全称 CommonJS,是 Node.js 支持的模块规范语法
- umd 是统一模块定义,兼容各种模块规范(Node.js、浏览器等),优先使用 umd
- 最新的模块规范是使用 import、export 关键字
2、通过 webpack 引入
安装 yarn add react react-dom
然后import:
import React from 'react'
import ReactDOM from 'react-dom'
- 这样的引入方式需要配置好 webpack
- 除了用 webpack ,也可以用 rollup、parcel 等工具
webpack 的配置较麻烦,React 提供了 create-react-app 工具来代替,即:
- 新手用 create-react-app
- 老手用 webpack/rollup
用 React 实现 +1 demo
const root = document.querySelector("#app")
let n = 0
const App = ()=>React.createElement("div", {className:"red"}, [
n,
React.createElement(
"button",
{
onClick(){
n += 1
ReactDOM.render(App(), root)
}
},
"+1"
)
])
ReactDOM.render(App(), root) //渲染到页面
说明
App1 = React.createElement("div", null, n) ---- React 元素
App2 = ()=>React.createElement("div", null, n) ---- React 函数组件
- 虚拟DOM
React.createElement的返回值看似是一个 DOM 对象,但实际上并不是真正的 DOM,称为虚拟 DOM 对象。
- DOM Diff 算法
通常用函数组件的形式 App2 来生成虚拟DOM,当数据变化时,再次运行App2()可得到新的虚拟DOM,React 会对比新旧两个虚拟 DOM,找出不同,然后局部更新视图。找不同的算法称为 DOM Diff 算法。
这种写法过于复杂!!
JSX -- JS 扩展版
何为 JSX
1、与 Vue 的 .vue 文件类比
JSX 是对上述 JS 的一种简化写法,可类比 Vue 的 .vue 文件
- Vue 有
.vue文件:
用 vue-loader 转译 .vue 文件(编译原理),将简单的 <template> 写法转译为复杂的 render 函数的形式
- 同理,React 有 JSX:
用 jsx-loader 转译 JSX,jsx-loader 已经被 babel-loader 取代,且内置到 webpack 中
2、JSX 对 React 元素的简化
-
JS 写法的虚拟 DOM:
const element = React.createElement("div", {className: "xxx"}, "n") -
JSX 写法的虚拟 DOM(直接写 XML 标签):
const element = <div className="xxx">n</div>
babel-loader 可将 JSX 写法转为 JS 写法
使用 JSX
方法一:CDN
-
引入 babel.js
-
在
<script type="text/babel"></script>标签中写 JSX 代码
示例(+1 demo):
<!DOCTYPE html>
<html>
...
<script src="https://.../react.xxx.min.js"></script>
<script src="https://.../react-dom.xxx.min.js"></script>
<script src="https://.../babel.min.js"></script>
<script type="text/babel">
// 以下为 JSX 代码
let n = 0
let fn = ()=>{
n+=1
ReactDOM.render(<App />, document.querySelector("#app"))
}
const App = () => (
<div>
<button onClick={fn}>+1</button>
</div>
)
ReactDOM.render(<App />, document.querySelector("#app"))
</script>
</html>
工作原理:
babel.js 将 <script type="text/babel"> 转译为 JS,并替换掉原 <script>
CDN 方法效率很低(原因如下),不推荐使用!
- 需要下载
babel.js - 需要在浏览器端将 JSX 转译为 JS
这些工作完全可以在 build 时完成
方法二:webpack + babel-loader
需要配置,新手不建议
方法三:create-react-app
安装:yarn global add create-react-app
创建目录:create-react-app react-demo
示例
App.js 导出一个 React 函数组件:
import React from "react"
const App = ()=>{
return (
<div>一个App组件</div>
)
}
export default App
由于 webpack 默认会用 babel-loader 处理 JS 文件,而 JSX 也需要用 babel-loader 处理,所以可以直接在 App.js 中使用 JSX 的语法,无需命名为 App.jsx。
在 index.js 引入:
import React from "react"
import ReactDOM from "react-dom"
import App from './App.js'
ReactDOM.render(<App />, document.querySelector("#app"))
JSX 基本语法总结
-
JSX 中 XML 标签可以视为一种值的类型,如
<div>hello JSX</div>,表示一个虚拟 DOM 对象,它相当于React.createElement("div", null, "hello JSX") -
在标签内取变量或其他 JS 表达式要用
{}包围 :<div> {n} </div><div> {fn()} </div>
-
标签上可直接写 DOM 的属性(并非 HTML 标签的属性)
<div className="xxx">---- 属性值为字符串,直接用引号<div onClick={fn}>---- 属性值为 JS 表达式,要用{}包围
-
return语句要习惯性地加上()--- 防止return undefined,例如:
function App(){
return
<div>
...
</div>
} //这样会return undefined