React随笔
React 中的this
React 的官方文档里写的自定义的方法都需要用 bind 方法绑定一下才能使用,否则 this 会出现指向问题,那究竟是为什么呢?
探讨一
1 |
|
React
中的 Babel
使用了严格模式,所以写的全局的 this
指向的是undefined
而且 demo
方法并不写在 Person
类中,所以这个 this
也不会指向 Person
的实例对象
探讨二
1 |
|
我们看下面的例子
1 |
|
p1 的原型链上是可以找到 study 方法的,然后把 study 方法赋值给了 x。也就相当于在栈上多了一个指针指向了 study 方法,这下 x 就彻底和 p1 没有关系了
另外,再明确一点:_类中自定义的方法,都会启用局部严格模式_。也就是说 this 的值是 undefined
也就是说 x 执行后 this 值就是 undefined
验证:类中自定义的方法,都会启用局部严格模式
1 |
|
分析 this.demo = this.demo.bind(this)
为什么用 bind()就可以解决 this 指向问题呢?
1 |
|
分析this.demo = this.demo.bind(this)
等号右侧的第一个 this 指向的是实例对象,这个实例对象上有 demo 方法吗?有,但是实在原型链上的。
bind 方法做两件事:
- 将 this 牢牢的绑定到传入的参数上
- 返回一个新的函数
等号右边第二个 this,也就是传入的参数,这个 this 指的就是实例对象
这样的话返回了一个新的函数,而且这个函数牢牢的绑定到了实例对象上,并不需要去原型链上找了
再看等号左侧,将返回的新函数赋值给了 this,这个 this 也是 Person 实例对象,用相同的方法名接收一下
这样就可以使用了
我们这样再去看onClick={this.demo}
,这下再点击后执行的就是实例自身上的 demo 方法了。
2021-12-25 更新—— React17 对比新旧生命周期
新的生命周期和旧的生命周期相比,即将废弃三个钩子:componentWillMount
、componentWillUpdate
、componentWillReceiveProps
新增了两个新的钩子:getDerivedStateFromProps
、getSnapshotBeforeUpdate
剩下的都和之前的一样的
2021-12-16 更新—— React 配置代理
单个代理可以直接在package.json
文件中配置proxy
多个代理则需要新建一个setupProxy.js
文件,配置如下:
1 |
|
create-react-app
脚手架会自动找到setupProxy.js
文件,并将配置加入到 webpack 中
2021-12-27 更新—— React 路由原理
靠的是 H5 推出的 history 上的 API
1 |
|
2021-12-28 更新—— 全局事件总线
用第三方库mitt
或者pubsub
,可以实现多层级的组件之间的通信
2021-12-30 更新—— React 的 setState()
异步执行
多个 setState()会推到一个任务队列里面,将多次执行合并为一个来执行。
setState()的几种写法
1 |
|
setState()方法里的第二个参数是一个回调函数,该函数能拿到设置之后的值
2021-12-31 更新—— 无副作用
在 React 里经常看到无副作用
这个词,它表示它只对自身有影响对自身以外的无影响,所有的输出都是由我的输入来决定的。
发一个请求,设置了 localstorage,对外部进行了操作这都叫做副作用
React 生命周期
- 组件初始化阶段 initialization, 比如 constructor
- 组件挂载阶段 mount
- componentWillMount 组件挂载到 DOM 前调用,只会被调用一次, 这里写 setState 不会引起组件重新渲染
- render 返回一个 react 元素, react 根据此函数的返回值渲染 DOM. 不能在这里 setState
- componentDidMount 组件挂载到 DOM 后调用, 且只会被调用一次
- 组件的更新阶段 update
- componentWillReceiveProps(nextProps) 触发于 props 引起的组件更新过程中
- shouldComponentUpdate(nextProps, nextState) 比较之前和当前的 props state 是否有变化
- componentWillUpdate(nextProps, nextState) render 方法前执行
- render
- componentDidUpdate(preProps, preState)
- 组件的卸载阶段 unmount
- componentWillUnmount 卸载前调用, 在这里可以清理一些定时器
componentWillMount
,componentWillReceiveProps
,componentWillUnmount
在 React17 不建议使用,即将被废弃
2022-06-30 更新 React 的虚拟 DOM
在 React,我们操作的元素被称为 React 元素,并不是真正的原生 DOM 元素。
React 通过虚拟 DOM,将 React 元素和原生 DOM,进行映射,虽然操作的是 React 元素,但是这些操作最终都会在真实的 DOM 中体现。
虚拟 DOM 的好处:
- 降低 api 复杂度(远离原生的复杂的 dom 操作)
- 解决兼容性问题
- 提升性能(减少 DOM 的不必要操作)
每当我们调用 root.render()时,页面就会发生重新渲染
React 会通过 diffing 算法,将新的元素和旧的元素进行比较
通过比较找到发生变化的元素,并且只对变化的元素进行修改,没有发生的变化不予处理。
比较两次数据时,React 会先比较父元素,父元素如果不同,直接所有元素全部替换。父元素一致,再去逐个比较子元素,直到找到所有发生变化的元素为止。
在 JSX 中显示数组时,数组中的每一个元素都需要设置一个唯一的 key,否则控制台会报警告。
重新渲染页面时,React 会按照顺序依次比较对应的元素,当渲染一个列表时如果不指定 key,同样也会按照顺序进行比较。如果列表的顺序永远不会发生变化,不加 key 没有问题。但是如果列表的顺序会发生变化,这可能会导致性能问题。
- 尽量用元素的 id 来做 key
- 用遍历的 索引 index 来做 key,没有意义,仍然会全部更新
- 当元素的顺序不会发生变化时,用索引 index 做 key,没有问题