三、React应用(基于React脚手架)
大约 3 分钟约 948 字
create-react-app
创建 React 应用
(一)使用 1.React 脚手架
- xxx 脚手架
- 用来帮助程序员快速创建一个基于 xxx 库的模板项目
- 包含了所有需要的配置(语法检查、jsx 编译、devServer......)
- 下载好了所有相关的依赖
- 可以直接运行一个简单效果
- React 提供了一个用于创建 React 项目的脚手架库:
create-react-app
- 项目的整体技术架构为:React + Webpack + ES6 + ESLint
- 使用脚手架开发的项目的特点
- 模块化
- 组件化
- 工程化
2.创建项目并启动
1)全局安装
npm i -g create-react-app
2)切换到想创建项目的目录,使用命令
- 默认安装的是 React18,需要降级为 React17
- https://blog.csdn.net/qq3163566/article/details/125842229
npx create-react-app hello-react
3)进入项目文件夹
cd hello-react
4)启动项目
npm start
3.React 脚手架项目结构
public ---- 静态资源文件夹
------ favicon.icon ------ 网站页签图标
------ index.html -------- 主页面
------ logo192.png ------- logo 图
------ logo512.png ------- logo 图
------ manifest.json ----- 应用加壳的配置文件
------ robots.txt -------- 爬虫协议文件
src ---- 源码文件夹
------ App.css -------- App 组件的样式
------ App.js --------- App 组件
------ App.test.js ---- 用于给 App 做测试
------ index.css ------ 样式
------ index.js ------- 入口文件
------ logo.svg ------- logo 图
------ reportWebVitals.js ------- 页面性能分析文件(需要 web-vitals 库的支持)
------ setupTests.js ------- 组件单元测试的文件(需要 jest-dom 库的支持)
4.功能界面的组件化编码流程(通用)
1)拆分组件
- 拆分界面
- 抽取组件
2)实现静态组件
- 使用组件实现静态页面效果
3)实现动态组件
- 动态显示初始化数据
- 数据类型
- 数据名称
- 保存在哪个组件
- 交互(从绑定事件监听开始)
(二)组件的组合使用 —— TodoList 案例
1.import 原则
- 第三方库往上靠
- 自定义文件往下靠
- 样式文件放最后
2.动态初始化列表
- 如何确定将数据放在哪个组件的 state 中?
- 某个组件使用:放在其自身的 state 中
- 某些组件使用:放在他们共同的父组件 state 中(官方称此操作为 状态提升 )
3.关于父子组件通信
- 父组件给子组件传递数据:通过
props
传递 - 子组件给父组件传递数据:通过
props
传递- 要求父组件先给子组件传递一个函数
1)父组件
import React, { Component } from "react";
import Header from "./components/Header";
export default class App extends Component {
state = {
tasks: [
{ id: "001", name: "吃饭", done: true },
{ id: "002", name: "睡觉", done: true },
{ id: "003", name: "打代码", done: false },
{ id: "004", name: "看动漫", done: true },
],
};
// 添加一项新任务
addTasks = (taskObj) => {
this.setState({
tasks: [taskObj, ...this.state.tasks],
});
};
render() {
const { tasks } = this.state;
return (
<div className="todo-container">
<div className="todo-wrap">
<Header addTasks={this.addTasks} />
</div>
</div>
);
}
}
2)子组件
import React, { Component } from "react";
import { nanoid } from "nanoid";
import PropTypes from "prop-types";
import "./index.css";
export default class Header extends Component {
// 对接收的props进行:类型、必要性的限制
static propTypes = {
addTasks: PropTypes.func.isRequired,
};
// 添加一项新任务
handleKeyUp = (event) => {
// 解构赋值获取key,target
const { key, target } = event;
// 处理空输入
if (target.value.trim() === "") {
alert("输入不可为空!");
return;
}
// 判断是否是回车键
if (key !== "Enter") return;
// 创建一个task对象
const task = { id: nanoid(), name: target.value, done: false };
// 将task对象传递给App组件
this.props.addTasks(task);
// 清空输入框
target.value = "";
};
render() {
return (
<div className="todo-header">
<input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认" />
</div>
);
}
}
4.注意
defaultChecked
和checked
区别
1)defaultChecked
只在页面初次渲染时起作用,state
更新也无法改变勾选状态checked
可以动态更新,但需要配合onChange
事件监听- 类似的还有:
defaultValue
和value
重要
状态在哪个组件,操作状态的方法就在哪个组件