React 是一个用于构建用户界面的 JavaScript 库,主要特点有:
声明式渲染:设计好数据和视图的关系,数据变化 React 自动渲染,不必亲自操作DOM
组件化:页面切分成多个小部件,通过组装拼成整体页面,利于代码复用
本文通过写个简单的 TodoList 实例,不求甚解,熟悉下 React 的开发过程。
1. 安装 Node.jsNode.js 是一个运行环境,类似 jdk,用以支持在服务端运行 JavaScript。
您可以在这里下载安装包:
以绿色版安装为例,将 node-v10.16.1-win-x64.zip 解压到 E:\software\ 并命名为 node-v10.16.1
在 Path 环境变量中增加两项:
E:\software\node-v10.16.1\ E:\software\node-v10.16.1\node_global在 cmd 中使用 node -v 显示版本号,表示安装成功。
Node.js 中有个 npm 软件包管理器,可以很方便的管理下载和使用第三方开源包,类似 maven,使用 npm -v 显示版本号,表示 npm 也没有问题。
绿色版安装完成后一些必要的配置:
npm config set prefix "E:\software\node-v10.16.1\node_global"设置全局安装的模块存储路径
npm config set cache "E:\software\node-v10.16.1\node_cache"设置下载缓存的存储路径
npm config set registry https://registry.npm.taobao.org`设置 npm 下载源为淘宝镜像
简单使用:
npm install xxx: 安装到项目目录
npm install -g xxx 安装到全局目录
npm install -save xxx: 安装到项目目录,并在 package.json 中的 dependencies 节点记录依赖
npm install --save-dev xxx: 安装到项目目录,并在 package.json 中的 devDependencies 节点记录依赖
2. 脚手架创建项目React 官方出的脚手架工具 create-react-app ,可以一键创建一个 Web 应用程序:
cmd> npm install -g create-react-app cmd> cd E: cmd> create-react-app react-todoapp cmd> cd react-todoapp脚手架会在当前目录创建一个 react-todoapp 目录:
react-todoapp ├── README.md ├── node_modules ├── package.json ├── package-lock.json ├── .gitignore ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── index.css ├── index.js ├── logo.svg └── serviceWorker.js └── setupTests.js目录中主要的文件和文件夹说明:
README.md: 项目简介,支持 Markdown 语法
node_modules: 项目的依赖包,类似 Maven Repository
package.json: 配置项目依赖的第三方包,类似 pom.xml
package-lock.json: 锁定第三方包的版本号,保证 npm install 版本一致
public: 公开资源,网站路径,类似 nginx 的 html 目录
src: 核心组件代码文件
为了便于开发,删除目录中不必要的文件,最终结构如下:
react-todoapp ├── README.md ├── node_modules ├── package.json ├── package-lock.json ├── .gitignore ├── public │ └── index.html └── src ├── App.css ├── index.js ├── TodoApp.js ├── TodoItem.js └── TodoList.js接下来,设计与实现一个 TodoList 的例子,我们把所有代码过一下,敲一遍,先不管为什么,跑起来,最后再整理下知识点。
3. 实例 TodoApp主要实现功能有:
添加一个待办事项
删除一个待办事项
勾选复选框标记事项已完成
如图所示,总共将页面拆分成了三个组件:TodoApp, TodoList 和 TodoItem。
3.1 index.js 入口文件应该可以类比 java 的 main 方法,在 src 目录新建 index.js 内容如下:
// 引入 React, ReactDOM import React from 'react'; import ReactDOM from 'react-dom'; // 引入 TodoApp 组件 import TodoApp from './TodoApp'; // 将渲染结果挂在到 root 节点,该节点在 index.html 中 ReactDOM.render( <React.StrictMode> <TodoApp /> </React.StrictMode>, document.getElementById('root') );先导入需要使用的组件(类),然后调用它们提供的方法和服务,有没有些许眼熟?
3.2 TodoApp.jsTodoApp 设计了页面整体布局,它包含全部数据以及操作这些数据的方法,是其他两个组件的父组件:
import React, { Component } from 'react'; import TodoList from './TodoList'; import './app.css'; class TodoApp extends Component { constructor(props) { // 构造方法,props 应该是父类的一个成员变量 super(props); this.state = { // 组件状态数据 text: '', items:[{id: 1, status: 1, text: "去月球"},{id: 2, status: 0, text: "去火星"}] }; // 设置 this 指向,默认 undefined this.handleChange = this.handleChange.bind(this); this.handleAdd = this.handleAdd.bind(this); this.handleComplete = this.handleComplete.bind(this); this.handleDelete = this.handleDelete.bind(this); } // 渲染解析 jsx render() { return ( <div className="todo"> <h3 className="text-center">Todos App</h3> <TodoList items={this.state.items} handleComplete={this.handleComplete} handleDelete={this.handleDelete} /> <input className="input" type="text" placeholder="添加新任务" value={this.state.text} onChange={this.handleChange} /> <button className="btn-add" onClick={this.handleAdd}>添加</button> </div> ); } handleChange(e) { this.setState({ text: e.target.value }) } handleAdd(e) { e.preventDefault(); if (this.state.text.length === 0) { return; } const newItem = { id: Date.now(), text: this.state.text, status: 0 }; this.setState({ items: [...this.state.items, newItem], text: '' }); } handleComplete(taskid) { // 临时变量,不直接修改原数据 let items = this.state.items; let findItem = items.find(item => item.id === taskid); findItem.status = findItem.status === 0 ? 1 : 0; this.setState({ items: items }); } handleDelete(taskid) { let items = this.state.items; items = items.filter(item => item.id !== taskid); this.setState({ items: items }); } } export default TodoApp; 3.3 TodoList.js