react库
用于构建用户界面的JavaScript库
注意!!! React是一个库不是一个框架
react库的特点:
- 声明式:
- 组件化:
- 一次学习,随处编写:版本的变动较小
react的生态现在是阿里做的
一、创建项目
通过script标签引入,在学习时一般直接引用cdn引入
通过react的脚手架,创建项目进行开发,部署
1
2
3
4
5
6
7// 1.安装脚手架
cnpm installl -g create-react-app
// 2.创建项目
create-react-app 01helloworld
// 开发时运行的环境
cd 01helloworld
npm start
二、React的渲染
使用jsx的写法,可创建js元素
注意:jsx的元素,必须要有一个根元素
1 | let root = <h1>这是根元素</h1> |
使用函数的方式创建元素
1 | let desc = "这是根组件"; |
三、React组件传值
关于组件的创建
- 组件的创建第一种方法:函数式组件
1 | function App () { |
- 组件的创建第二种方法:变量式创建
1 | const app = new App({ |
定义类的方式
1 | import { render } from "react-dom"; |
注意!!!这是React16之后的写法,在这之前的js还没有扩展出类写法,因此在这之前一般采用以下的写法:
1 | const App = React.createClass({ |
四、JSX
JSX的优点:
- JSX执行更快,编译为JavaScript代码时进行优化
- 类型更安全,编译过程中能即时发现错误
- JSX编写模板更加简单快速(相对而言)
注意!!!
- Jsx与Vue类似,必须要有一个根节点
- 正常的普通HTML必须小写,大写会默认认为是组件
JSX内部的表达式:{}
- 可以使用大多数的JS表达式:如: 变量,函数,对象,条件运算符,三元运算符
- 可以直接使用HTML,不需要进行任何处理
- 在使用类名的时候尽量使用className,因为class是React的内置关键字
总结:
- JSX由HTML的元素构成
- 中间如果需要加入变量,需要用括号括起来
- 可以使用表达式,表达式中可以使用JSX对象
- 属性和对象内容都是用括号插入内容
五、JSX-Style样式
1.class中,不可以存在多个class属性
1 | <div class='abc' class={'active'}></div> |
2.style样式中,如果存在多个单词时,第二个单词开始必须首字母大写,或者用-引起来,否则会报错
1 | let exampleStyle = { |
3. 多个类共存的操作
1 | let ele4 = ( |
4. 关于JSX的注释
1 | {/* 必须在表达式内书写注释,否则报错 */} |
六、条件循环
1. 条件判断
2. 循环
1. 简单的循环方式
1 | let arr = ['芜湖','起飞','南通','哈哈哈哈']; |
2. 简化后的循环方式
使用数据的map方法,对每一项数据按照jsx的形式进行加工,最终得到1个每一项都是jsx对象的数值,
七、组件
注意ReactDom.render()一般只会放一个根组件,但是一个根组件可以加载无数的组件
1. 函数式组件
1 | import {render} from "react-dom"; |
2. 类组件
1 | import {render} from "react-dom"; |
3. 复合组件
1 | class ChildCom extends React.Component{ |
4. 函数式与类组件的区别
- 类组件可以自定义事件,函数式组件不方便设置事件
- 内容定死,只传一些简单的参数,就是使用函数式组件,即为静态组件
- 函数式组件操作简单,但可支持功能较少
- 类组件用于交互和数据修改
注意!!!无论是类组件还是函数式组件的调用都是
这种的方式
八、props
1. 父传递子组件
要对子组件进行控制,如:是否显示,则只需要在父组件处传入一个布尔值即可:
1 | // 父组件 |
2. 子组件向父组件数据传递
1 | // 实现子传父 |
九、React事件
特点:
- react事件,绑定事件的命名,驼峰命名
- 传入1个函数,而不是字符串,如果的
事件对象:
React返回的事件对象是代理处理后的事件对象,如果想要查看事件对象的具体值,必须之间输出事件对象的属性
原生的JS,可以直接使用return false,来阻止浏览器的默认行为
但是因为React代理处理了原生JS使得return false 变为无效,要阻止浏览器的默认行为就使用 e.preventDefault
React事件传参
使用函数的方式
1
<button onClick={(e)=>{this.parentEvent1('msg:hello world',e)}}>点击</button>
不使用箭头函数方式
1
2
3<button onClick={function (event) {
this.parentEvent1('msg:hello world',event)
}.bind(this)}> 点击 </button>
十、组件条件循环渲染
1. 三元运算符
1 | // 组件1 |
2. 列表循环渲染
十一、React制作疫情地图
1.疫情数据的API接口
注意!!! (不允许跨域请求)
https://c.m.163.com/ug/api/wuhan/app/index/feiyan-data-list?t=1580892891419
2.写入一个Json数据文件
3.导入Json数据
1 | import jsonData from "./feiyan"; |
4.设置(设计)数据模型
1 | let provinceObj = { |
5.进行数据累加
1 | jsonData.data.list.forEach((item,index)=>{ |
6.对数据进行排序
1 | // 对数组进行降序排序 |
7.将数据渲染至页面上
1 | import React from 'react'; |
十二、React的生命周期
生命周期的3个状态:
- mount:挂载
- update:数据更新
- unMount:卸载
十三、 表单
- 必须绑定value值
- 必须绑定onChange事件
十四、Ajax与React
本次小案例运用到的是技术有:
- axios网路请求
- express后端框架
- React前端框架
- AJax异步请求
1.API接口
https://i.snssdk.com/ugc/hotboard_fe/hot_list/template/hot_list/forum_tab.html?activeWidget=1
获取到首页的信息后查看Ajax的数据请求
可以获取到首页的数据请求
以及
2.建议服务器
- express –view=ejs react-serve
- cd react-serve
- npm install
3.axios的安装
- npm install axios
十五、React实现todoList
复习一下React的事件机制
涉及到的技术有:Ref以及键盘事件
十六、关于prop-types
1.prop-types介绍
prop-types是用于限制父组件传给子组件的数据类型,以及是否为必须的数据
prop-types的报错只是表明与声明的规范不一致导致的报错,并不一定会影响最终的DOM渲染
2. prop-types的安装
自从React V15之后,prop-type就作为单独的插件,需要另外的安装,而且也不是必须使用的插件
安装:
npm i prop-types –save
3.prop-types的使用
1 | // 1. 导入prop-types |
当然还有另外一种写法:
1 | class MyComponent extends React.Component { |
十七、React插槽
组件中写入自定义内容,这些内容可以被识别和控制,
1.原理
插槽的内容会默认传入props.children处,直接调用可以使用this.props.children
组件中的HTML内容直接全部插入,调用{this.props.children}
根据HTML内容的不同插入的内容也不同的,(即对组件插槽进行处理)
1 | // 父组件 |
十八、 React 路由
1.安装
cnpm i react-router-dom –save
2.路由的三大组件
- Router:所有的路由的根组件
- Link:用于页面的跳转相当于HTML的A标签
- Route:路由根组件下面匹配的组件
3.写一个简单的路由
1 | <Router basename="/admin"> |
4.路由传参
1 | <div id="app"> |
5.路径切换
路由的切换,默认采用的push方法,可以前进后退
replace:进入的该路由之后,就会将该路由设置为默认首页,此时不可以前进或者后退
1 | <Router basename="/admin"> |
6.动态路由
1 | <Router basename="/admin"> |
7.路由重定向
1 | // 当访问到LoginInfo组件的是否,该组件会跟条件重定向至不同的内容 |
8.路由函数式导航
1 | class ChildCom extends React.Component { |
9.Switch组件
让switch组件内容的route只匹配1次,只要匹配到了内容,便不会往下匹配
1 | <Router> |
十九、Redux状态管理树
解决React数据管理(状态管理),用于中大型项目,数据比较庞大,且组件间的数据交互多的情况下使用
Redux的特点:
- Store:数据仓库,保存数据的地方
- state:state是一个对象,数据仓库的所有数据都放到state里面
- action:与Vue有点区别,action就是一个动作用于触发数据改变的方法,不是用于Ajax异步请求
- dispatch:将action动作触发成方法
- Reducer:是一个函数,通过获取动作,改变数据生成一个新的状态state从而改变页面
1.安装Redux
cnpm install redux –save
2.初始化仓库
1 | // 1.导入redux |
3.React-redux
安装:
cnpm i react-redux –save
概念:
- Province
使用:
初始化仓库数据
1
2
3
4
5
6
7
8
9
10
11
12
13function reducer(state=0,action) {
switch (action.type) {
case "add":
state.num++;
break;
case "decrement":
state.num--;
break;
default:
break;
}
return {...state}
}
实例化数据仓库
1
const store = createStore(reducer);
数据的获取–映射函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 设置action
let addAction = {
type:"add"
}
// 将state映射到props函数中
function mapStateToProps(state) {
return {
value:state.num,
}
}
// 将修改state数据的方法,映射到props,默认会传入store里的dispatch方法
function mapDispatchToProps(dispatch) {
return {
onAddClick:()=>{
dispatch(addAction)
},
onDecrementClick:()=> dispatch({type:"decrement"})
}
}
将两个映射函数结合成一个新的App函数
1
2
3
4const App = connect(
mapStateToProps,
mapDispatchToProps
)(Counter)渲染组件
1
2
3
4
5
6ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)