react学习
1.react是Facebook公司开发的最初用于ins的网站搭建
2.库和框架的概念
库:小而巧 只提供了特定API 可以很方便的从一个库换到另一个库 代码几乎不会改变
框架:大而全 框架提供了一整套的解决方案,所以切换到其他的框架比较困难
3.模块化和组件化及其优点
模块化:从代码出发分析 把一些可复用的代码 抽离为单个的模块,便于项目的维护和开发
组件化:从ui出发分析 把一些可复用的ui界面 抽离为单独的组件 (随着项目的开发,组件积累的越来越多,很方便就能把现有的组件拼接成完整的页面)
vue如何实现组件化 通过.vue文件创建对应的组件 分成三部分 template (结构) script(行为) style(样式) 缺一不可
react如何实现组件化 react中有组件化的概念 但是没有像vue一样这样的组件模版文件 一切都已js来表现
移动开发方向
vue结合weex技术 可以迁移到移动端 weex技术阿里自己系列软件在用
react 结合react native 可以无缝迁移到移动端 大公司用的多
4.react的核心概念
(1).虚拟dom
dom的本质 浏览器的概念 用js对象表示页面上的元素,浏览器提供了操作dom对象的API
react中的虚拟dom 框架中的概念 是程序员用js对象来模拟 页面上的dom和dom嵌套
为什么要实现虚拟dom 为了实现页面中dom元素的高效更新
dom树的概念 (一个页面呈现的过程)浏览器请求服务器获取页面html代码 -> 浏览器要先在内存中,解析dom结构,并在浏览器内存中渲染出一棵dom树 ->浏览器把dom树渲染在页面上
如何把性能最优 ->按需更新 如何按需更新 ->获取内存中的新旧两棵dom树进行对比,得到需要修改的dom元素 如何获取dom树 -> 浏览器并未提供获取dom树的api ->程序员手动模拟dom 树 如何模拟dom树 ->对象与数组结合 var tree = {
tagName:'div',
childrens:[{tagName:'p'},'lalala']
}
程序员用js对象的方式手动模拟dom树和嵌套关系 就是虚拟dom 目的:使页面高效更新
(2).diff算法(different)
tree diff 新旧两颗dom树逐层对比的过程,当整棵树逐层对比结束,则所有需要按需更新的元素都能被找到
component diff 在进行tree diff的时候,每一层中组件级别的对比
若对比前后,组件类型相同,则暂时认为此组件不需要被更新
若对比前后,组件的类型不同,则需要移除旧组件,创建新组件,并追加到页面上
element diff 在进行组件对比的时候若出现组件相同,则需要进行元素级别的对比。
5.问题记录
在使用react时 初始创建react项目用npm install -g create-react-app 报错 错误信息为 Error: EACCES 即没有权限 此时在指令前加sudo即可执行
6.前端思想pwa progressive web application
以前端的方式写手机app react中的体现 在index.js中有 import registerServerWorker from './ registerServerWorker' 引入之后用户第一次打开页面需联网 之后若在无网络环境下打开也会显示联网时的页面
manifest.json是在使用pwa时 对首次页面的缓存 可以在该页面设置快捷方式的图标和网址 颜色等
7.使用react的步骤
sudo npm install -g create-react-app -> cd Desktop -> create-react-app +文件名 -> cd 文件名 -> npm start 就会打开新建的页面 每次调试 npm run start
8.在app.js中 import React, { Component } from 'react'; 去掉,{}中的东西 等同于class App extends React.Component这种写法
render函数返回什么 页面显示什么 在用export default +类名 返回出去
9.ES6 解构赋值 ???
10.jsx语法需要引入react
11.jsx语法
(1).直接在js文件中写入标签 无需引号
(2).可以将自定义的组件以标签形式引入 注意首字母必须大写
(3).jsx语法规定 函数返回的标签群必须被包裹在一个标签中
(4).react16提供了Fragment标签 解决既满足(3)又不想在页面中显示最外层标签的方法
(5).jsx中的变量要用{}包裹
(6).jsx如何写注释 {//或者/**/} 是开发时注释
12.constructor(props)为类的构造函数 默认有个props参数 在其中执行super(props) 即执行父类的构造函数 构造函数中this.state可以存放数据
13.事件绑定时需要通过bind(this)改变this指向 state中提供setxxx用来改变state中的值 以传入对象的形式
14.map???
15.ES6展开运算符
[...this.state.list,xxx] 意味将之前的数组内容拿过来
16.react做循环时,需要在每个循环中加入key值 不加不报错 但警告
17.immutable ->即state不允许我们做任何修改 若想修改就拷贝个副本 不然之后的性能优化会出现问题
18.jsx 中写class名时推荐写成className 因为在该语法下默认class为类
19.若想达成在input输入框中加入标签在页面中显示的话,在你想出现的标签上写 属性dangerouslySetInnerHTML = {{__html:item}} 但是可能会被注入攻击
20.父组件以属性的方式传给子组件数据 子组件以this.props.xxx的形式接收
子组件以父组件传递过来的方法传递数据给父组件
21.react代码优化
先引入组件 在引入样式
bind(this)的时候可以拿到顶端写 提高性能
新版react对setState 进行修改 之前是对象的形式 新版是函数形式 返回对象 即this.setState(()=>{
return {inputValue:e.target.value}}) 但会报错 报错原因是写成了函数就会出现异步操作 所以要在函数上面用常量保存时间的相关参数
22.ES6return的简写是括号
23.setState()可以接收个参数是prevState 表示上一个state 等同于this.state
24.react的特点
声名式开发 (只操作数据)
可以与其他框架共存
组件化开发 (组件开头字母 要大写)
单向数据流 (只能父组件向子组件传值,子组件不能改变父组件传过来的值)
视图层框架 (只处理数据和页面渲染,其他复杂组件间的传值要借助其他框架)
函数式编程 (对前端自动化测试带来方便)
25.切换node版本
npm install -g n
n 版本号
26.action
是行为的抽象
是普通js对象
一般由方法是生成
必须有一个type (唯一的)
27.store = reducer + state
reducer里有createstore 会生成store
28.
29.总结一下:redux的设计思想简单的说;
第一步:action :不管三七二之一;模拟出事件;
第二步:reducer: 开发中自然有多个reducer;
新建一个reducer文件只做一件事;吧多个reducer合并成一个reducer.
使用combineReducers方法来将多个reducer合并成一个;每个reducer会生成一个新的state;将多个reducer合并成一个reducer;那也就等同于将多个小的state合并成一个大的state对象;
第三步: const store = createStore(reducers); 将state交给store管理;
第四步:action返回一个对象;这个对象交给store管理;其中reducer也是store来管理的;每次触发一个action;就会执行所有的reducer;
可以认为以上种种都是为了容器组件服务的;在containers里面计算得到state和返回的action纯对象;这样将action对象和state合并为容器组件的props;继而将props合并到UI组件中去!!
第五步:容器组件中connect方法的参数mapStateToProps方法可以得到所有的reducer对应的state从中获取指定值然后合并为组件的props;
mapDispatchToProps方法可以返回需要用的纯对象(action);方法会自动将这个对象合并到组件的props中。
30.propTypes 子组件对父组件传递过来的数据类型进行强校验
先引入prop-types包 import PropTypes from "prop-types"
再在子组件写入 TodoItem.propTypes = {
content: PropTypes.string , 注意大小写
deleteItem: PropTypes.func,
index:propTypes.number.isRequired 他的判定还有许多 比如既可以是数字也可以是字符串就写成:PropTypes.oneOfType([PropTypes.number,PropTypes.string]) 可以看一下官方文档不写require的时候 如果父组件没传递index的值的话程序也不会报错 但是加了之后如果不传index的值的话就会报错 这时就可以给index一个默认值 TodoItem.defauliProps = {
index:3
}
31.Props,State,Render函数
当组件的state或props发生改变,render函数就会重新执行
当父组件的render 函数被重新执行时 子组件也会被重新执行
32.dom即documentfragment文档碎片
虚拟dom就是js对象用来模拟真是dom["div",{id:"abc"},["span",{},"hello worid"]]
js创建一个真实dom对象代价极高 要调用webapplication级别的API 很消耗性能
33.在react底层中,先生成虚拟dom,然后再根据虚拟dom生成真实dom
jsx -> createElement -> 虚拟dom (js对象) ->真实dom
所以运用jsx只是让我们在开发的时候方便一点 运用偏向底层的React.createElement({})也可以达成目的
34.虚拟dom的优点
提升性能
可以跨域
35.setState是异步函数 为了提升性能
36.react的虚拟dom是同层比对 若该层不一样就舍弃下面的层重新渲染
37.key值最好不是k的原因是k不稳定 所以对于比对的话不好 提高性能
38.react中的ref的使用
dom元素的引用 之前的e.target能拿到dom元素 现在
![](https://img2018.cnblogs.com/blog/1243464/201811/1243464-20181108121959887-1610520796.png)
初始化 -> 挂载 -> 更新 -> 移除 每个组件都有的生命周期函数
40.生命周期函数的使用场景
(1).render函数的性能优化
正常情况下父组件的render函数执行就会带着子组件的render函数一起执行 但有时是没必要并且损耗性能的 这时可以通过钩子函数来避免
其他的react的性能优化
setState异步
虚拟dom 同层比较 key值
(2). ajax的请求
不能写在render里,因为render多次执行
所以写在componentDidMount里
react没有ajax的内置功能,所以用第三方模块
如 axios npm add axios
import axios from 'axios'
axios.get("请求的地址")
.then(()=>{alert("xxx")})
.catch(()=>{alert('error')})
41.ajax接口数据模拟
Charles可以抓取浏览器发出的请求 并且路由到你想要的地方 即中间的代理服务器
42.react的css过渡效果
transition:all 1s ease-in;
43.react的css动画效果
@keyframes
定义动画效果 👆
使用动画效果 👇
加了forward之后动画会固定在最后一帧 不然会回到初始状态
44.react-transition-group模块实现动画效果
npm install react-transition-group --save 引入
import { CSSTransition } from 'react-transition-group'
提供很多钩子函数 具体可在GitHub上搜索看具体
TransitionGroup 配合 CSSTransition能实现成组动画效果