react 是什么?
react是一个声明式的, 高效且灵活的用于构建用户界面的javaScript的库.
react组件
jsx文件,里面是jsx语法生成的dom
jsx语法
jsx除了是文件后缀外,在组件内还是一种语法.
`<img />`这个jsx语法是`React.createElement('img')`
一种看上去很像html的语法
### 虚拟dom 和 diff 算法
用js通过算法计算出来的dom对象,叫虚拟dom
diff算法的原理:同层对比,发现不一致,就直接用新的虚拟dom替换旧的,且停止向下对比
样式绑定(css)
类名样式:className
内联样式(独一的):`style={{color:'red'}}` 第一个{}用来执行js的
样式作用域
默认情况下,样式在组件内引入后,作用域是全局的
使用name.module.css命名样式后,组用于就只是当前组件内生效
资源引入img
背景图就是使用相对路径
前景图img用`require('相对路径').default`
函数里只要返回的是dom元素,这个函数就叫做函数组件,官方叫做无状态组件
React.createElement('div',{className:'app'}'我是一个组件')
{ }js表达式,专门用在虚拟dom里使用js内容的
函数组件--无状态组件--ui组件
好处:
渲染快(就是个函数,调用就行了),代码简洁
缺点:
纯函数组件确实很多react特性,比如生命周期没有
适用:
写dom片段,所以又叫做ui组件
第一个根组件一定是拥有全部react特性的,最次也得是class
函数组件或者另外的类组件作为参数给到插槽里面
const Title = (props) => <h2>我是需要用点组件的方式渲染出来</h2>
api和指令
dangerouslySetInnerHeml(非dom属性)
渲染字符串dom片段,底层做了防注入攻击,但一般情况下,不推荐使用
react.createElement
创建虚拟dom的,`<div/>`jsx语法是他的语法糖,也是对它的封装
React.Component
创建类组件的基类,包含着全部react特性
React.Fragment
占位的点组件,用于包裹集合元素,
优点是不会渲染任何标签
缩写:`<></>`
属性和状态
props
属性,规则:自定义属性必须全部小写;
原生的属性需要而外的注意:class 变成了 className
for 变成了 htmlFor;tabindex变成了tabIndex
### 属性默认值
`App.defaultProps = {props:defaultValue}`
### 属性类型验证
需要引入`prop-type`包依赖
`App.propTypes = {prop:propTypes.String}`
### 属性的入参写法
写在普通的虚拟dom上的叫属性
写在自定义组件上的是传参方式
参数值的类型有:字符串,数组,数字,布尔值等
如果是对象类型的话,需要使用扩展运算符展开
## state
状态,与vue里的data一样的功能
修改state只能使用setState
# 事件函数
1.在class类里,事件函数的this指向问题
三种解决方案:
- 1.直接在事件绑定函数后面加`.bind(this)`[不推荐]
- 2.在constructor里事先绑定`.bind(this)`[也不推荐]
- 3.声明函数的时候使用箭头函数绑定this[推荐]
2.阻止事件冒泡,默认事件的方法
.stopPropagation()禁止冒泡行为
.preventDefault()禁止默认行为
# 生命周期
## 概念
生,老,病,死 === 人的生命周期
初始化,挂载,更新,销毁 === 程序的生命周期
## 定义
事物的不同阶段发生的变化叫做生命周期
## api
- constructor 初始化阶段
- render 解析jsx语法阶段
- componentDidMount 完成挂载
- componentDidupdate 完成更新
- componentWillUnmount 完成卸载
- static getDerivedStateFromProps(props,state) 修改state的值
- 通过props计算出来state值,它挥发改掉setState设置的值
- 在挂载阶段和更新阶段都会触发0
- 返回对象则替换state,返回null则不修改任何数据
- shouldComponentUpdate(props,state)
- 性能优化的一部分
- 执行时机:当props和state发生改变时,还没有在render里体现的时候;
- 默认返回true,返回false则阻止render的执行,也就相当于阻止更新了.
- getSnapshotBeforeUpdate(prevProps, prevState)
- 获取dom元素的
- 入参是上次的旧值不是新值
- 在最近一次渲染输出(提交到dom节点)之前调用。
它使得组件在发生更新之前从dom中捕获一些信息(列入,滚动位置)。
此生命周期的任何返回值将作为参数传递给componentDidUpdate
# hook
是react自16.8版本后新出的一套api,其目的是为了让函数组件拥有全部的react特性.
## 设计思想
函数式编程
## useState
状态管理:
- 语法:`const[value,setValue] = useState(default)`
- 定义:让函数组件拥有和类组件一样的状态
- 数组里的第一个值是渲染到页面上的数据state,后面的值是用来修改前面数据的方法,等价于内组件的setState
- 不能直接修改value 只能用setvalue函数去修改,这样才能让组件进行更新
- - [注意]useState返回的修改函数和类组件setState执行逻辑不一样
- setState是把新旧值合并,useState返回的修改函数是传进来的新值直接把旧值替换
## useEffect 生命周期
定义:把componentDidMount,
componentDidUpdate,
componentWullUnmount,
shouldComponentUpdate合并成一个叫做useEffect函数了
### componentDidMount(页面挂载完成)
```js
useEffect(function(){
console.log('页面挂载完成')
},[])
```
### componentWillUnmount(卸载)
```js
useEffect(()=>{
retutn function(){
//当组件被销毁的时候调用的,在这个函数里做准备卸载的一些事情
//例如:清除定时器...
}
})
```
### componentDidUpdate
```js
useEffect(function(){
console.log("当props或state发生改变时,这个函数就相当于更新的钩子函数")
})
```
### shouldComponentUpdate
```js
useEffect(()=>{
console.log("只有'数据'发生改变我才执行")
},['数据'])
```
# 受控与非受控
## 受控组件
- 受react控制的叫做受控组件
- 例子:当一个input的value绑定了state,那么该组件叫做受控组件
## 非受控组件
- 不受react控制的,行为完全由用户控制的叫做非受控
- 例子: input类型是file的就是纯粹的非受控组件
- defaultValue 给非受控组件添加一个初始值,但不影响更新
- ref 获取非受控组件节点,进行操作或读取
# React.lazy
使用lazy动态加载组件,使用Suspense包裹被懒加载的组件
语法:
```js
const Home = React.lazy(()=>import('path/Home.jsx'))
//当Home组件尚未加载完成前,显示备用内容
return <React.Suspense fallback={备用内容}>
<Home></Home>
</React.Suspense>
```
# 高阶组件
它不是api,是一种组合模式.目的是为了复用类组件里的方法
定义:一个函数接收一个组件返回回一个类组件.就叫高阶组件
顶级API
React.component,
React.PureComponent,
React.createElement,
React.cloneElement,
React.children,
React.Fragment,
React.createRef,
React.useRef,
React.createContext,
React.lazy,
React.Suspense,
React.forwardRef,
React.useState,
React.Effect,
React.memo,
React.useMemo,
ReactDOM.render,
ReactDOM.createPortals,
React.useCallback
## 性能优化
1. shouldComponentUpdate是否阻止组件更新
2. memo
3. useMemo
4. useCallback
5. pureComponent 等价于自动调用shouldComponentUpdate
6. React.lazy 组件的按需加载
React组件通信方式?
- 组件向子组件通信
- 子组件向父组件通信
- 中间组件层层传递 props
- 使用 context 对象
React路由传参方式?
1.params; 2.query; 3.state
React中的类组件与函数组件不同点?
类组件内部拥有状态 state,函数组件无法拥有状态 state,现在在 react16.8 的版本可以用 react hook 解决
类组件通过继承成新的类,函数组件通过高阶组件返回新组件