[Web Fronted] 前端基础框架: React
序
- 部分开源项目是基于 Web 前端框架 React 构建的,有必要了解一二。
避免一脸懵逼,不知道怎么修改相关代码和配置
概述: React
React 的简介
React
起源于Facebook
的内部项目
因为该公司对市场上所有
JavaScript MVC
框架 都不满意,就决定自己写一套,用来架设
做出来以后,发现这套东西很好用,就在2013年5月开源了。
React
是一个用于动态构建用户界面的JavaScript
库(只关注于视图)。
React
主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
React 的特点
-
声明式设计与编码 − React采用声明范式,可以轻松描述应用。
-
高效 − React通过对DOM的模拟,最大限度地减少与DOM的交互。
高效(优秀的Diffing算法)
-
灵活 − React可以与已知的库或框架很好地配合。
-
JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
-
Component & 组件化编码 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
-
单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
单向数据绑定
-
虚拟 DOM
-
React Native 编写原生应用
React 高效的原因
- 使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。
- DOM Diffing算法, 最小化页面重绘。
React 官网
- https://react.dev/ 【现官网】
- https://react.docschina.org/ 【中文官网】
React 的主要原理
- 传统的web应用,操作DOM一般是直接更新操作的
但是我们知道DOM更新通常是比较昂贵的。
而React为了尽可能减少对DOM的操作,提供了一种不同的而又强大的方式来更新DOM,代替直接的DOM操作。
就是VirtualDOM
,一个轻量级的虚拟的DOM,就是React抽象出来的一个对象,描述dom应该什么样子的,应该如何呈现。
通过这个Virtual DOM去更新真实的DOM,由这个Virtual DOM管理真实DOM的更新。
- 为什么通过这多一层的
Virtual DOM
操作就能更快呢? > + 这是因为React有个diff
算法,更新VirtualDOM并不保证马上影响真实的DOM,React会等到事件循环结束,然后利用这个diff算法,通过当前新的dom表述与之前的作比较,计算出最小的步骤更新真实的DOM。
最明显的一点好处就是React所谓的
dom diff
,能够实现delta
级别的dom更新。
当有数据变动导致DOM变动时,React不是全局刷新,而是通过它内部的dom diff 算法计算出不同点,然后以最小粒度进行更新。
这也是React
号称性能好的原因。
Facebook为什么要建造React
- Facebook的工程师在做大型项目时,由于他们非常巨大的代码库和庞大的组织,使得MVC很快变得非常复杂,每当需要添加一项新的功能或特性时,系统的复杂度就成级数增长,致使代码变得脆弱和不可预测,结果导致他们的MVC正在土崩瓦解,所以Facebook认为MVC不适合大规模应用,当系统中有很多的模型和相应的视图时,其复杂度就会迅速扩大,非常难以理解和调试,特别是模型和视图间可能存在的双向数据流动。
基于上面的原因,Facebook认为
MVC
无法满足他们的扩展需求,为了解决上述问题需要“以某种方式组织代码,使其更加可预测”,于是他们提出的Flux
和React
来实现。
React Hello World Application
Hello World Application
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello, React Application!</title>
<!-- 引入 React 核心库 -->
<!-- <script src="../js/react.development.js"></script> -->
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<!-- 引入 react-dom 用于支持 react 操作 DOM -->
<!-- <script src="../js/react-dom.development.js"></script> -->
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- 引入babel:
1. ES6 ==> ES5
2. jsx ==> js
-->
<!-- <script src="../js/babel.min.js"></script> -->
<!-- 生产环境中不建议使用 | 在浏览器中使用 Babel 来编译 JSX 效率是非常低的 -->
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
</head>
<body>
<!-- 准备好一个 DOM 容器 -->
<div id="test"></div>
<!-- 方式1 -->
<!-- <script type="text/babel">
// 1. 创建虚拟 DOM
const VDOM = <h1>Hello,React</h1>
// 2. 渲染到页面中的指定 DOM
// ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(VDOM,document.getElementById('test'))
</script> -->
<!-- 方式2 -->
<script type="text/babel">
// 简单的 React 组件
function App() {
return <h1>Hello, React Application!!</h1>;
}
const root = ReactDOM.createRoot(document.getElementById("test"));
// 渲染 React 组件到 DOM
root.render(<App />);
</script>
</body>
</html>
效果
基础库的安装与导入
CDN与本地引入方式
- React 库: 用于构建用户界面。
- ReactDOM 库:用于在浏览器中渲染 React 组件。
- Babel Standalone 库:用于在浏览器中即时编译 JSX 语法。(不建议生产环境中使用)
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<!-- 生产环境中不建议使用 | 在浏览器中使用 Babel 来编译 JSX 效率是非常低的 -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/babel-standalone/6.26.0/babel.min.js"></script>
NPM Install 导入方式
创建项目,并导入React框架
mkdir my-react-app
cd my-react-app
npm init
# 注:填写新npm项目的信息
npm install react@18.2.0 react-dom@18.2.0 react-scripts@5.0.1 cra-template@1.2.0 babel-standalone@6.26.0
# 注:安装react依赖,babel-standalone 可不安装
创建并编辑index.html
mkdir -p my-react-app/public
vim index.html
编辑内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<!-- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> -->
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
创建并编辑App.js
组件及自定义的组件
- 创建并编辑
Add.js
组件
mkdir -p my-react-app/src
vim my-react-app/src/Add.js
编辑内容:
Add.js
import React,{Component} from 'react';
import PropTypes from 'prop-types';
class Add extends Component{
constructor(props){
super(props);
this.state={
todoInput:''
}
this.add = this.add.bind(this);
}
add(){
//读取文本框值
const todo = this.todoInput.value.trim();
//值合法性判断
if(!todo){
return;
}
//添加
this.props.addTodo(todo);
this.todoInput.value='';
}
render(){
return (
<div>
<input type="text" ref={input=>this.todoInput=input}/>
<button onClick={this.add}>Add #{this.props.count+1}</button>
</div>
);
}
}
Add.propTypes={
count:PropTypes.number.isRequired,
addTodo:PropTypes.func.isRequired
}
export default Add;
- 创建并编辑
List.js
组件
mkdir -p my-react-app/src
vim my-react-app/src/List.js
编辑内容:
List.js
import React,{Component} from 'react';
import PropTypes from 'prop-types';
class List extends Component{
render(){
const {todos} = this.props;
return (
<ul>
{
todos.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
);
}
}
List.propTypes = {
todos:PropTypes.func.isRequired
}
export default List;
- 创建并编辑
App.js
组件
mkdir -p my-react-app/src
vim my-react-app/src/App.js
编辑内容如下(可按自己需要另作编码)
import React, { Component } from 'react';
//import logo from './logo.svg';
//import './App.css';
import Add from './Add';
import List from './List';
class App extends Component{
constructor(props){
super(props);
this.state={
todos:['C#从入门到放弃','Java从入门到放弃','C++从入门到放弃']
}
this.addTodo = this.addTodo.bind(this);
}
addTodo(todo){
const {todos} = this.state;
todos.unshift(todo);
this.setState({todos});
}
render(){
const {todos} = this.state;
return (
<div>
<div>编程语言列表(Program Languages List)</div>
<Add count={todos.length} addTodo={this.addTodo}/>
<List todos={todos}/>
</div>
);
}
}
/**
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<h2>欢迎来到MyApp</h2>
</div>
<p className="App-intro">
你可以在 <code>src/App.js</code> 文件中修改。
</p>
</div>
);
}
}
**/
export default App;
编辑并创建index.js
vim src/index.js
src/index.js
: 这是 React 应用的入口文件。它是应用的启动点,通常在这里调用ReactDOM.render
将组件渲染到页面的根节点。
编辑内容:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
配置package.json
- 编辑/配置
package.json
更新:
scripts
"start": "set PORT=8081 && react-scripts start",
"build": "react-scripts build"
"test": "echo \"Error: no test specified\" && exit 1"
启动项目
npm run start
运行效果
NPM + create-react-app
导入方式
- 还可以使用
create-react-app
工具创建的react
开发环境:
import React from "react";
import ReactDOM from "react-dom";
function Hello(props) {
return <h1>Hello World!</h1>;
}
ReactDOM.render(<Hello />, document.getElementById("root"));
- Step1 安装 nodejs 和 npm / cnpm
在开始之前,确保你已经安装了 Node.js 和 npm,你可以通过以下命令检查它们是否已经安装:
node -v
npm -v
如果你的系统还不支持 Node.js 及 NPM 可以参考:
我们建议在
React
中使用CommonJS
模块系统,比如browserify
或webpack
,本篇使用webpack
。
国内使用
npm
速度很慢,你可以使用淘宝定制的cnpm
(gzip
压缩支持) 命令行工具代替默认的npm
:
$ npm install -g cnpm --registry=https://registry.npmmirror.com
$ npm config set registry https://registry.npmmirror.com
这样就可以使用 cnpm 命令来安装模块了:
$ cnpm install [packageName]
更多信息可以查阅: http://npm.taobao.org/。
- Step2 使用
create-react-app
快速构建 React 开发环境
- React 提供了一个官方工具
Create React App
,用于快速搭建React
项目。create-react-app
是来自于React
开发环境。create-react-app
自动创建的项目是基于Webpack
+ES6
。
- 执行以下命令创建项目:
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start
- 也可以使用
npx
命令来创建,npx
是npm 5.2.0
及更高版本中包含的一个工具,用于执行本地或远程的 npm 包:
npx create-react-app my-app
在浏览器中打开 http://localhost:3000/ ,结果如下图所示:
项目的目录结构:
my-first-react-app/
├── node_modules/
├── public/
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src/
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package.json
├── README.md
└── yarn.lock (或 package-lock.json)
- 目录和文件说明
node_modules/
存放所有项目的依赖包。这个目录由 npm 或 yarn 自动生成,包含了项目运行所需的所有第三方库和模块。
public/
存放静态文件,Webpack 不会对这个目录中的文件进行处理。public 目录下的文件会被直接复制到构建目录。
favicon.ico
:浏览器标签页上的小图标。index.html
:HTML 模板文件,React 组件将被挂载到这个文件中的 div 元素中。logo192.png
/logo512.png
: 不同尺寸的 React logo 图标。manifest.json
: Web 应用清单文件,用于定义应用的名称、图标等元数据。robots.txt
:用于告诉搜索引擎哪些页面可以被抓取。src/
存放应用的源代码。这里是你主要进行开发的地方。
App.css
: App 组件的样式文件。App.js
:主组件文件,定义了一个基础的 React 组件。App.test.js
: App 组件的测试文件。index.css
: 全局样式文件。index.js
: 应用的入口文件,负责渲染 React 组件到 DOM 中。logo.svg
: React logo 的 SVG 文件。reportWebVitals.js
: 用于性能监测的文件,可以帮助你了解和分析应用的性能。setupTests.js
: 用于设置测试环境的文件。.gitignore
列出 Git 应该忽略的文件和目录,例如 node_modules/ 和构建输出的目录。
package.json
项目的配置文件,包含项目信息、脚本、依赖项等。
README.md
: 项目的自述文件,包含项目的基本信息和使用说明。yarn.lock
/package-lock.json
: 锁定文件,记录了确切的依赖版本,确保在不同环境中安装的依赖一致。这个package-lock.json
是在npm install
时生成一份文件,用以记录当前状态下实际安装的各个npm package
的具体来源和版本号,以保证其他人在npm install
时大家的依赖能保证一致。
例如:
"dependencies": {
"@types/node": "^8.0.33",
},
向上标号
^
是定义了向后(新)兼容依赖,指如果types/node
的版本是超过8.0.33,并在大版本号(8)上相同,就允许下载最新版本的 types/node库包,例如实际上可能运行npm install时候下载的具体版本是8.0.35。波浪号
原来
package.json
文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,你每次npm install
都是拉取的该大版本下的最新的版本,为了稳定性考虑我们几乎是不敢随意升级依赖包的,这将导致多出来很多工作量,测试/适配等。
所以,package-lock.json
文件就出来了,当你每次安装一个依赖的时候就锁定在你安装的这个版本。
- 尝试修改 src/App.js 文件代码:
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>欢迎来到MyApp</h2>
</div>
<p className="App-intro">
你可以在 <code>src/App.js</code> 文件中修改。
</p>
</div>
);
}
}
export default App;
- 修改后,打开 http://localhost:3000/ (一般自动刷新),输出结果如下:
原理探究
创建虚拟DOM的方式
- 方式1:纯JS方式(一般不用)
- 方式2:虚拟DOM
虚拟DOM与真实DOM
- React提供了一些API来创建一种 “特别” 的一般js对象
const VDOM = React.createElement('xx',{id:'xx'},'xx')
上面创建的就是一个简单的虚拟 DOM 对象
-
虚拟DOM对象最终都会被React转换为真实的DOM
-
我们编码时,基本只需要操作
react
的虚拟DOM相关数据,react
会转换为真实DOM变化而更新界面。 -
虚拟DOM与真实DOM的区别
关于虚拟DOM:
- 本质是Object类型的对象(一般对象)
- 虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部生成并使用的。
- 虚拟DOM最终会被React转换为真实DOM,渲染在页面上;
<script type="text/babel">
// 1. 创建虚拟 DOM
const VDOM = (
<h1>Hello,
<span>React</span>
</h1>
)
// 2. 渲染到页面中的指定 DOM
// ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(VDOM,document.getElementById('test'))
const TDOM = document.getElementById('demo')
// console.log(typeof VDOM) // Object
// console.log(VDOM instanceof Object) // true
console.log('虚拟DOM',VDOM)
console.log('真实DOM',TDOM)
// 调试
debugger
</script>
React JSX
什么是 JSX ?
JSX
是React
的核心组成部分,它使用XML
标记的方式去直接声明界面,界面组件之间可以互相嵌套。
可以理解为在
JS
中编写与XML类似的语言,一种定义带属性树结构(DOM结构)的语法
它的目的不是要在浏览器或者引擎中实现,它的目的是通过各种编译器将这些标记编译成标准的JS语言。
-
虽然你可以完全不使用JSX语法,只使用JS语法,但还是推荐使用
JSX
,可以定义包含属性的树状结构的语法,类似HTML
标签那样的使用,而且更便于代码的阅读。 -
使用
JSX
语法后,你必须要引入babel
的JSX
解析器,把JSX
转化成JS
语法
这个工作会由
babel
自动完成。
同时引入babel
后,你就可以使用新的es6
语法,babel
会帮你把es6
语法转化成es5
语法,兼容更多的浏览器。
- 全称:
JavaScript XML
react
定义的一种类似于XML
的JS
扩展语法:
JS + XML
的本质:React.createElement(component, props, ...children)
方法的语法糖
- 作用: 用来简化创建虚拟DOM
- 写法:
var ele = <h1>Hello JSX!</h1>
- 注意1:它不是字符串, 也不是
HTML/XML
标签- 注意2:它最终产生的就是一个
JS
对象
-
标签名任意: HTML 标签或其它标签
-
标签属性任意: HTML 标签属性或其它
-
基本语法规则
- 遇到
<
开头的代码, 以标签的语法解析:html
同名标签转换为html
同名元素, 其它标签需要特别解析- 遇到以
{
开头的代码,以JS
语法解析: 标签中的js
表达式必须用{ }
包含
babel.js
的作用
- 浏览器不能直接解析
JSX
代码, 需要babel
转译为纯JS的代码才能运行- 只要用了
JSX
,都要加上type="text/babel"
, 声明需要babel
来处理
渲染虚拟DOM(元素)
- 语法: ReactDOM.render(virtualDOM, containerDOM)
- 作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
- 参数说明
- 参数一: 纯js或jsx创建的虚拟dom对象
- 参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)
JSX的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.title{
background-color: aliceblue;
width: 200px;
}
</style>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入 React 核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入 react-dom 用于支持 react 操作 DOM -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel:
1. ES6 ==> ES5
2. jsx ==> js
-->
<script src="../js/babel.min.js"></script>
<script type="text/babel">
let myData = 'Student'
let myId = 'ITStudent'
// 1. 创建虚拟 DOM
const VDOM = (
<div>
<h1 className="title" id={myId.toUpperCase()}>Hello,
<span style={{color:'white',fontSize:'20px'}}>{myData}</span>
</h1>
<input type="text" />
<Good></Good>
</div>
)
// 2. 渲染到页面中的指定 DOM
// ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</body>
</html>
JSX 的语法规则
- 定义虚拟DOM时,不要写引号;
- 标签中混入JS表达式时,要用 {}
- 样式的类名指定不要用class,要用className;
- 内联样式,要用style={{key:value}}的形式去写
- 只能有一个根元素
- 所有标签都必须闭合
- 标签的首字母:
- 若小写字母开头,则将该标签转化为html同名的元素,渲染到页面;若html没有同名的元素,则报错。
- 若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错;
模块与组件、模块化与组件化的理解
模块
- 理解:向外提供特定功能的js程序, 一般就是一个js文件
- 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
- 作用:复用js, 简化js的编写, 提高js运行效率
什么是模块化?当应用的js都以模块来编写的, 这个应用就是一个模块化的应用
组件
- 理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
- 为什么要用组件: 一个界面的功能更复杂
- 作用:复用编码, 简化项目编码, 提高运行效率
什么是组件化?当应用是以多组件的方式实现, 这个应用就是一个组件化的应用
函数式组件
<script type="text/babel">
// 1. 创建函数式组件
function MyComponent(){
// 这里的 this 是 undefined,因为 babel 编译,开启了严格模式
console.log(this)
// 一定需要有返回值
return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
}
// 2. 渲染到页面中的指定 DOM
// ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(<MyComponent />,document.getElementById('test'))
/*
执行 ReactDOM.render() 方法之后,发生了什么?
1. React 解析了组件标签,找到对应的组件
2. 发现这个组件是一个函数定义的,随后调用该函数,生成了一个虚拟DOM
3. 最后将虚拟DOM转化为真实DOM,呈现在页面中;
*/
</script>
- 函数式组件执行过程?
React
解析了组件标签,找到对应的组件- 发现这个组件是一个函数定义的,随后调用该函数,生成了一个虚拟DOM
- 最后将虚拟DOM转化为真实DOM,呈现在页面中;
类式组件
<script type="text/babel">
// 1. 创建一个类式组件
class MyComponent extends React.Component{
// render方法是放在原型上的
// render中的this是谁? -- 实例对象 <===> MyComponent组件实例对象
render(){
console.log('render中的this',this)
return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
}
}
// 2. 渲染到页面中的指定 DOM
// ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(<MyComponent />,document.getElementById('test'))
/*
执行 ReactDOM.render() 方法之后,发生了什么?
1. React 解析了组件标签,找到对应的组件
2. 发现这个组件是一个类定义的,随后new出来一个实例对象,并通过该实例调用原型上的render方法
3. 将render()返回的内容生成了一个虚拟DOM
4. 最后将虚拟DOM转化为真实DOM,呈现在页面中;
*/
let c = new MyComponent()
console.log(c)
</script>
- 类式组件执行过程?
- React 解析了组件标签,找到对应的组件
- 发现这个组件是一个类定义的,随后
new
出来一个实例对象,并通过该实例调用原型上的render
方法- 将
render()
返回的内容生成了一个虚拟DOM- 最后将虚拟DOM转化为真实DOM,呈现在页面中;
create-react-app
工具命令
- url
查看工具版本
$ create-react-app --version
5.0.1
帮助手册
$ create-react-app --help
Usage: create-react-app <project-directory> [options]
Options:
-V, --version output the version number
--verbose print additional logs
--info print environment debug info
--scripts-version <alternative-package> use a non-standard version of react-scripts
--template <path-to-template> specify a template for the created project
--use-pnp
-h, --help output usage information
Only <project-directory> is required.
A custom --scripts-version can be one of:
- a specific npm version: 0.8.2
- a specific npm tag: @next
- a custom fork published on npm: my-react-scripts
- a local path relative to the current working directory: file:../my-react-scripts
- a .tgz archive: https://mysite.com/my-react-scripts-0.8.2.tgz
- a .tar.gz archive: https://mysite.com/my-react-scripts-0.8.2.tar.gz
It is not needed unless you specifically want to use a fork.
A custom --template can be one of:
- a custom template published on npm: cra-template-typescript
- a local path relative to the current working directory: file:../my-custom-template
- a .tgz archive: https://mysite.com/my-custom-template-0.8.2.tgz
- a .tar.gz archive: https://mysite.com/my-custom-template-0.8.2.tar.gz
If you have any problems, do not hesitate to file an issue:
创建React应用程序
npx create-react-app {appName}
或
create-react-app {appName}
FAQ : React
Q: create-react-app my-app
时,报npm
同级依赖(peer dependency)错误:"While resolving: my-app@0.1.0 Found: react@19.0.0 ... Could not resolve dependency: peer react@"^19.0.0 ... " from the root project"(版本冲突/同级依赖与无法解析依赖树问题)
- 问题描述
$ create-react-app my-app
Creating a new React app in D:\Workspace\CodeRepositories\react-app\my-app.
Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...
added 1323 packages in 58s
266 packages are looking for funding
run `npm fund` for details
Initialized a git repository.
Installing template dependencies using npm...
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: my-app@0.1.0
npm ERR! Found: react@19.0.0
npm ERR! node_modules/react
npm ERR! react@"^19.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.0.0" from @testing-library/react@13.4.0
npm ERR! node_modules/@testing-library/react
npm ERR! @testing-library/react@"^13.0.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR!
npm ERR! For a full report see:
npm ERR! C:\Users\xxx\AppData\Local\npm-cache\_logs\2025-01-04T05_14_33_516Z-eresolve-report.txt
npm ERR! A complete log of this run can be found in: C:\Users\xxx\AppData\Local\npm-cache\_logs\2025-01-04T05_14_33_516Z-debug-0.log
`npm install --no-audit --save @testing-library/jest-dom@^5.14.1 @testing-library/react@^13.0.0 @testing-library/user-event@^13.2.1 web-vitals@^2.1.0` failed
- 原因分析
这个错误表明你当前的项目发现
package.json
中声明的依赖组件react
的版本为19.0.0,但正在尝试安装的@testing-library/react
这个库又需要一个特定的同级依赖react@"^18.0.0"
,导致解析依赖树失败、安装失败。
- 解决方法
参见: [nodejs] NPM 教程 - 博客园/千千寰宇
关键词:版本冲突
/同级依赖
/无法解析依赖树问题
/npm install xxxx --legacy-peer-deps
- 参考文献
Y 推荐资源
- 官网
- 快速入门教程
https://react.docschina.org/learn
教程:井字棋游戏 | https://react.docschina.org/learn/tutorial-tic-tac-toe
React 哲学 | https://react.docschina.org/learn/thinking-in-react
- 在线编辑与效果试验
- React JS Download & CDN
- React 官方
<!-- 生产环境中不建议使用 | 在浏览器中使用 Babel 来编译 JSX 效率是非常低的 -->
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
//development
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://fb.me/react-0.14.3.js"></script>
<script src="https://fb.me/react-dom-0.14.3.js"></script>
<script src="https://fb.me/react-with-addons-0.14.3.js"></script>
<script src="https://fb.me/react-dom-0.14.3.js"></script>
//production
<script src="https://fb.me/react-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
<script src="https://fb.me/react-with-addons-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
//npm方式
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(<App />, ...);
- 字节跳动的 React CDN 库
react.js: React 的核心库,用于构建用户界面。
react-dom.js: 提供与 DOM 相关的操作,用于在浏览器中渲染 React 组件。
babel.js: 用于将 ES6+ 代码转换为向后兼容的 JavaScript 版本,确保代码在不同浏览器中的兼容性。
- Staticfile CDN 的 React CDN 库
<script src="https://cdn.staticfile.org/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/18.2.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
- https://gitcode.com/open-source-toolkit/6a556/ (开源工具包 - React.js 核心文件包下载)
<script src="path/to/babel.js"></script>
<script src="path/to/react.js"></script>
<script src="path/to/react-dom.js"></script>
- React 开发者工具
使用 React 开发者工具检查 React components,编辑 props 和 state,并识别性能问题。
- 浏览器扩展: 调试 React 构建的网站最简单的办法就是安装 React 开发者工具浏览器扩展。它可用于几种流行的浏览器:
现在,如果你访问一个用 React 构建 的网站,你将看到 Components 和 Profiler 面板。
- Safari 和其他浏览器 : 略
- 移动端(React Native):略
X 参考文献

本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!