创建文件夹
mkdir+文件夹名称
创建脚手架
create-react-app + 文件夹名称
yarn 淘宝镜像源
yarn config set registry https://registry.npm.taobao.org -g
yarn 相关知识
yarn / yarn install 等同于npm install 批量安装依赖
yarn add xxx 等同于 npm install xxx —save 安装指定包到指定位置
yarn remove xxx 等同于 npm uninstall xxx —save 卸载指定包
yarn add xxx —dev 等同于 npm install xxx —save-dev
yarn upgrade 等同于 npm update 升级全部包
yarn global add xxx 等同于 npm install xxx -g 全局安装指定包
引入react
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/7.0.0-beta.3/babel.js"></script>
<script type="text/babel"></script>
函数组件无this指向 无state 无生命周期
核心语法 :jsx
- {js的表达式 不包括if(){} for()}
- < 遇见就是解析html
- 一个react元素 应该只有唯一的根节点
React灵魂:
1.props :父传子 不可改变
2.state:可在constructor 中this.state定义
概念:react元素是react组件的一部分
组件:
a:声明组件 函数式组件
函数式组件 {
1.参数 props 2.首字母大写 3.返回值 React元素
}
类组件 {
1.class A extends React.Component
2 render()React元素 放到此方法中执行
3 props 前面加this(和构造的this) 只能取值不能赋值
}
旧的生命周期 react16版本前
三个阶段 加载 更新 卸载
新生命周期 react17版本
## 阶段都有三个
新生命周期钩子
static getDerivedStateFromProps
用法:
触发时间:
实例创建之后
每次获取到新的props或者新的state(即setState)之后
参数
nextProps
nextState
返回值
如果返回一个Object,则相当于进行一次setState操作(注意,这里返回对象虽然改变了state,但不会再次触发此函数)
如果为null,则不更新state
如果无返回值(即默认return undefined),报错
如果返回一个基本类型值(如return 666;),则与返回null无区别
这里需要注意的是:
getDerivedStateFromProps是一个静态方法,this为undefined,不指向实例,所以也拿不到实例的属性和方法。至于为什么要将此方法设计为静态方法,官方文档解释:以后的组件将进行异步渲染,防止实例属性的被不安全访问,编写出异步兼容的代码
此方法不提供一个prevProps的参数,官方解释为,首次执行此方法,prevProps是null,那么每次调用此方法都要判断一次,很耗性能。其次,如果大家以后都习惯没有prevProps的日子,那么react就不保存prevProps的引用了,节省内存,提高性能(心里一万匹***奔腾而过)
如果要访问prevProps,只能将一些props的属性记录到state里面去了
不能同上述提到即将要被删除掉的三个生命周期钩子同时使用
getSnapshotBeforeUpdate
用法:
触发时间:update发生的时候,在render之后,在组件dom渲染之前
参数:prevProps, prevState(prevState为上一次更新中getDerivedStateFromProps方法执行后state的值)
返回值可以为任意值,且返回值将作为componentDidUpdate的第三个参数
这里需要注意的是:
与componentDidUpdate成对使用,否则会报错
不能同上述提到即将要被删除掉的三个生命周期钩子同时使用
为什么要删除三个生命周期钩子
其实官方解释是,很多react用户(包括我)都存在错误的使用这三个生命周期钩子的行为,导致以后异步渲染时,会导致极大的性能损耗,所以强制将这三个钩子删除掉(v17版本之后,现在还是可以使用的)。那接下来看看在这三个生命周期到底存在什么错误的用法:
componentWillMount
错误做法:
天真地认为在这里请求异步数据,首屏渲染就会有数据了
在此添加事件监听方法
在此初始化state(根据props进行setState)
缺点:
在此发起异步数据请求之后,会立刻调用render方法,那么首屏渲染还是没有数据
服务器渲染,不会调用componentWillUnmount方法,那么在此钩子里面添加的事件监听方法就无法被浏览器移除,导致内存泄露;同时,在此钩子请求异步数据,也无法首屏渲染数据(原因同上一点),返回到前端还是空白页面。
上面提到多,渲染可被打断,如果被打断,那么就可能会多次调用此钩子,导致多次请求数据,消耗性能
优化
在constructor里面进行state的初始化
在componentDidMount里面请求异步数据和添加事件监听方法(因为此时能够确保componentWillUnmount钩子一定会执行,就可在这个地方进行销毁事件监听器,回收内存)
解决服务端渲染的问题,可以查阅一下react的同构直出的方法
componentWillReceiveProps
错误做法:
根据前后props数据的对比更新state
根据前后props数据的对比请求异步数据
缺点:
更新state方式不优雅
职能不专,同时进行setState和获取异步数据等会触发新一轮组件更新的操作
渲染可被中断,会多次请求数据
优化:
使用getDerivedStateFromProps返回值来更新state
在componentDidUpdate获取数据
componentWillUpdate
错误做法:
根据新的state发起异步数据请求
在此进行外部函数调用(如nextProps.someMethod())
记录更新前一些节点的属性(这个做法没错,只是现在有更好的方式)
缺点:
异步数据和外部函数调用请求的缺点同前面两个钩子的一样
记录的信息如果放在state中,需要额外的判断(会进行两次更新)
优化:
在componentDidUpdate 在此处数据请求和外部函数调用
在getSnapshotBeforeUpdate记录当前节点信息,记录的信息通过返回值传递给componentDidUpdate作为第三个参数(省内存,仅一次更新)
总结
新生命周期的思想就是:确保渲染完成之前不做任何会引发重新渲染的操作
新生命周期流程图(来自react官网)
https://img-blog.youkuaiyun.com/20180814160812259?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5nd3g2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
原文:https://blog.youkuaiyun.com/zhangwx6/article/details/81667631