一、知识储备
l 基本熟悉HTML&CSS
l 了解JavaScript 语言
l 理解DOM
l 熟悉JavaScript ES6 语法及特征
l Nodejs 和npm 的安装部署
二、学习目标
l 了解React 概念及相关术语,如Babel、Webpack、JSX、组件、属性、状态、生命周期
l 构建简单的React 应用
三、React 是简介
· React 是一个JavaScript 库,目前最流行的库之一,github超过10万星
· React不是一个框架(与Angular 不一样)
· React 由Facebook 创建开源的项目
· React 用于前端构建用户接口(UI)
· React 是MVC层中的View 层
React最重要的方面之一是,你可以创建组件,就像自定义的、可重用的HTML元素一样,来快速有效地构建用户界面。React 还使用状态和道具简化了数据的存储和处理方式。
四、部署和安装
(一)静态页面
第一种方法不是设置 React 的流行方法,也不是我们将执行本教程其余部分的方式,但是如果您曾经使用过像 jQuery 这样的库,它将是熟悉且易于理解的,如果您不熟悉 Webpack,这是最不可怕的入门方法, 巴别塔和节点.js。
让我们从创建一个基本的索引.html文件开始。我们将在头部加载三个js- react、react-DOM 和babel。我们还将使用名为 root 的 id 创建一个 div,最后我们将创建一个脚本标记,你的自定义代码将驻留其中。
Index.html |
// React code will go here |
React :react 最上层api
React DOM: 增加DOM 的方法
Babel: JavaScript 编译器,可以将ES6 以上的代码转为老旧浏览器也能运行
全量代码如下:
Index.html |
class App extends React.Component { render() { return } } ReactDOM.render( |
打开浏览器http://localhost:3000
(二)创建React App单页应用
命令行 |
npx create-react-app react-demo cd react-demo&& npm start |
工程文件结构
创用
src/index.js |
import React, { Component } from 'react' import ReactDOM from 'react-dom' import './index.css' class App extends Component { render() { return (
) }} ReactDOM.render( |
(三)React 开发工具
有一个名为React开发人员工具的扩展,它将使您的工作在使用React时更加轻松。下载适用于Chrome的 React 开发工具(https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi),或者你喜欢使用的任何浏览器。
(四)JSX: JavaScript + XML
正如你所看到的,我们一直在我们的 React 代码中使用看起来像 HTML 的东西,但它并不完全是 HTML。这是 JSX,它代表脚本 XML。使用JSX,我们可以编写看起来像HTML的东西,也可以创建和使用我们自己的类似XML的标签。以下是 JSX 分配给变量的外观。
JSX |
const heading = |
使用 JSX 对于编写 React 并不是必需的。背后其实是运行 createElement,它采用标记、包含属性的对象和组件的子级,并呈现相同的信息。下面的代码将具有与上面的 JSX 相同的输出
不使用 JSX |
const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!') |
JSX实际上更接近于JavaScript,而不是HTML,因此在编写它时需要注意一些关键差异。
l className代替class来添加 CSS 类,因为class是 JavaScript 中的保留关键字。
l JSX 中的属性和方法是驼峰大小写 - onclick将变为onClick。
l 自结束标记必须以斜杠结尾 - 例如
JavaScript 表达式也可以使用大括号(包括变量、函数和属性)嵌入到 JSX 中。
const name = 'Tania'const heading = |
JSX比在普通的JavaScript中创建和附加许多元素更容易编写和理解,这也是人们如此喜欢React的原因之一。
(五)组件 Component
到目前为止,我们已经创建了一个组件 - 应用组件Component。React 中的几乎所有内容都由组件Component组成,这些组件可以是类组件class Component,也可以是简单组件 simple Component。
大多数 React 应用程序都有许多小组件,所有内容都加载到主应用程序组件中。组件通常也获取自己的文件,因此让我们更改项目以执行此操作。
下面演示一下拆分组件 App
src/index.js |
import React from 'react' import ReactDOM from 'react-dom' import App from './App' import './index.css' ReactDOM.render( |
src/App.js |
import React, { Component } from 'react' class App extends Component { render() { return (
) }} export default App |
类组件 Class Components
让我们创建另一个组件。我们将创建一个表。制作“Table.js”,并用以下数据填充它。
src/Table.js | ||||||||||
import React, { Component } from 'react' class Table extends Component { render() { return (
) }} export default Table |
src/App.js |
import Table from './Table' import React, { Component } from 'react'import Table from './Table' class App extends Component { render() { return ( ) }} export default App |
简单组件Simple Components
简单组件Simple Components 是一个函数
src/Table.js | ||
const TableHeader = () => { return (
)} |
src/Table.js | ||||||||
const TableBody = () => { return (
)} |
合并后如下:
src/Table.js |
const TableHeader = () => { ... } const TableBody = () => { ... } class Table extends Component { render() { return ( ) }} |
简单组件 simple component 与 class component 可以混合使用
Class 组件 必须包含render 函数,return只能返回一个顶级元素
简单组件simple component |
const SimpleComponent = () => { return } |
类组件 class component |
class ClassComponent extends Component { render() { return }} |
组件属性 Props
我们将 props 作为参数传递,并通过数组进行映射,以便为数组中的每个对象返回一个表行。此映射将包含在 rows 变量中,我们将以表达式的形式返回该变量。
src/Table.js | ||
const TableBody = (props) => { const rows = props.characterData.map((row, index) => { return (
) }) return {rows} } class Table extends Component { render() { const { characterData } = this.props return ( ) }} |
调用Table 组件,设置属性characterData
App.js |
return (
|
属性Props是将现有数据传递给 React 组件的有效方法,但是该组件无法更改道具 - 它们是只读的。在下一节中,我们将学习如何使用状态来进一步控制在 React 中处理数据。
状态State
现在,我们将角色数据存储在变量的数组中,并将其作为道具传递。这是一个很好的开始,但想象一下,如果我们希望能够从数组中删除一个项目。使用 props,我们有一个单向数据流,但是使用状态,我们可以从组件更新私有数据。
您可以将状态视为应保存和修改的任何数据,而不必将其添加到数据库中 - 例如,在确认购买之前在购物车中添加和删除项目。
创建 state
Src/App.js |
class App extends Component { state = {} } |
该对象将包含要存储在状态中的所有内容的属性。这里是characters。
Src/App.js |
class App extends Component { state = { characters: [], } } |
添加数据如下:
Src/App.js |
class App extends Component { state = { characters: [ { name: 'Charlie', // the rest of the data }, ], }} |
获取状态值:this.state.characters
修改状态值:this.setState();//注意修改值必须使用setState ,直接使用this.state.characters=xx 是没用的。
下面举例说明删除一个字符的操作
src/App.js |
removeCharacter = (index) => { const { characters } = this.state this.setState({ characters: characters.filter((character, i) => { return i !== index }), }) } |
src/App.js |
render() { const { characters } = this.state return ( )} |
通过Table 组件,将属性参数传递给 TableBody 组件
Table.js |
const Table = (props) => { const { characterData, removeCharacter } = props return ( ) } |
通过按钮点击 触发removeCharacter 实现属性的删除
Table.js | |||
|
提交表格数据Submitting Form Data
前面已经实现数据修改至state 状态,实际项目需要将修改反馈给后台甚至存储到数据库。
创建一个Form 组件
Form.js |
import React, { Component } from 'react' class Form extends Component { initialState = { name: '', job: '', } state = this.initialState } |
希望form 数据也发生变化后状态state 数据也变化
Form.js |
handleChange = (event) => { const { name, value } = event.target this.setState({ [name]: value, })} render() { const { name, job } = this.state; return ( type="text" name="name" id="name" value={name} onChange={this.handleChange} /> type="text" name="job" id="job" value={job} onChange={this.handleChange} /> );} export default Form; |
Form.js |
import Form from './Form' return (
|
App.js |
handleSubmit = (character) => { this.setState({ characters: [...this.state.characters, character] })} |
并绑定hadleSubmit事件
App.js |
新增submitForm方法,完成提交数据状态变化
Form.js |
submitForm = () => { this.props.handleSubmit(this.state) this.setState(this.initialState)} |
Button绑定点击事件至提交方法
Form.js |
效果如下:
通过API 拉取数据Pulling in API Data
通常React应用需要通过API获取数据。
Form.js |
import React, { Component } from 'react' class App extends Component { state = { data: [], } // Code is invoked after the component is mounted/inserted into the DOM tree. componentDidMount() { const url ='https://prism3d.cn/api?search=react+example&format=json&origin=*' fetch(url) .then((result) => result.json()) .then((result) => { this.setState({ data: result, }) }) } render() { const { data } = this.state const result = data.map((entry, index) => { return }) return }} export default App |
构建和部署Building and Deploying a React App
开发环境:编译、热更新
生产环境:编译、发布
执行命令 |
npm run build |
在package.json中增加即将部署的地址
package.json |
"homepage": "https://prism3d.cn/react-demo", |
在script 部分加上 部署命令predeploy 和 deploy
package.json |
"scripts": { // ... "predeploy": "npm run build", "deploy": "gh-pages -d build" } |
安装gh-pages 工具包
执行命令 |
npm install --save-dev gh-pages |
执行build 命令,构建静态页面
执行命令 |
npm run build |
执行deploy命令,部署页面
执行命令 |
npm run deploy |
然后就可以通过
https://prism3d.cn/react-demo 访问了。