react的生命周期
挂载期
- constructor(),组件的构造函数,用来初始化state
- componentWillMount(),初始化渲染前时调用
- componentDidMount(),初始化渲染后调用
更新期
- componentWillReceiveProps(),父组件修改组件的props时会调用
- render(),每次渲染时候会调用
- componentWillUpdate(),组件更新前调用
- shouldComponentUpdate(),组件更新时调用,主要判断组件要不要更新
- componentDidUpdate(),组件更新后调用
卸载期
- componentWillUnmount(),组件卸载时调用
react引入Fiber架构之后的生命周期
挂载
- constructor(),组件的构造函数,用来初始化state
- getDerivedStateFromProps(),初始化/更新时调用,使用 props 来派生/更新 state。
- componentDidMount(),初始化渲染后调用
更新 - shouldComponentUpdate(),组件更新时调用,主要判断组件要不要更新
- render(),每次渲染时候会调用
- getSnapshotBeforeUpdate(),返回值会作为第三个参数给到 componentDidUpdate。它的执行时机是在 render 方法之后,真实 DOM 更新之前。可以同时获取到更新前的真实 DOM 和更新前后的 state&props 信息。
- componentDidUpdate(),组件更新后调用,从 getSnapshotBeforeUpdate 获取到的值
卸载 - componentWillUnmount(),组件卸载时调用
对比一下,React 16 废弃的是哪些生命周期:
- componentWillMount;
- componentWillUpdate;
- componentWillReceiveProps
这些生命周期的共性,就是它们都处于 render 阶段,都可能重复被执行,而且由于这些 API 常年被滥用,它们在重复执行的过程中都存在着不可小觑的风险。
为什么废弃这些生命周期,因为引用了Fiber架构,render 阶段是允许暂停、终止和重启的,这就导致 render 阶段的生命周期都是有可能被打断重复执行
react和vue区别
https://zhuanlan.zhihu.com/p/508817213
mvc->mvvm的过渡,对比mvc与mvvm
参考springMVC的思想:
最近做项目中的有挑战和难度的事情
虚拟滚动的实现【尝试实现大数据量的时候,列表怎么优化】
https://blog.51cto.com/youthfighter/5461161
为什么不用外接库?【存疑,前端?】
react出现hook的原因
Hook 是 React 16.8 的新增特性,说白了就是一些可以让你在函数组件里使用React state 及生命周期等特性的函数。
-
原因:
-
1、在组件之间复用状态逻辑很难 ,原有解决方案:render props、高阶组件、providers、consumers(貌似说的是组件间状态的传递)
- 缺点:
- 嵌套地狱
- 需要改变组件结构
这说明了一个更深层次的问题:React 需要为共享状态逻辑提供更好的原生途径。
- 缺点:
-
2、生命周期中包含不相关的逻辑
例如,我们一般通过,componentDidMount和componentDidUpdate来获取数据, 会将很多不相关的处理逻辑同时放在componentDidMount;
在componentWillUnmount中设置事件监听,componentDidMount中清除事件监听,就导致相关而且需要对照修改的代码分开,维护时很容易出现bug。 -
3、Class 组件难以理解
需要理解this工作机制,需要区分class组件和函数组件的使用场景,class不能很好的压缩,并且会使热重载出现不稳定的情况。
-
4、Hook出现前,函数式组件的局限
函数组件无法使用内部状态,必须是纯函数,而且也无法提供完整的生命周期机制。
-
fiber架构出现的原因
因为在fiber之前当有状态发生变化时,react会递归所有的vDom(虚拟节点),那么此时如果节点过多,会导致其他事件延后,造成卡顿,即之前的react递归遍历虚拟dom的时候无法停止,一旦递归无法停留下来。
fiber使react能够异步可中断工作任务,并且可以在浏览器空闲时,从中断处继续往下工作(具体怎么中断,机智稍微复杂一点,需要专门研究,先简单记忆引入Fiber的原因)。
react调度器怎么判断事件优先级
兄弟组件通信的方法
https://blog.csdn.net/qq_35484341/article/details/88872567
- 通过父组件传递,缺点是会导致父组件下的所有组件都触发更新
- 使用观察者模式(也叫发布订阅模式)
- 使用Flux 与 Redux
redux的数据流
https://juejin.cn/post/7251170829970325564
redux数据的基本流程,简单的说就是view dispatch一个action后,通过对应reducer处理,然后更新store,最终views根据store数据的改变重新渲染界面
中间件的执行时机
Redux 中间件执行时机:在 dispatching action 和 到达 reducer 之间
没有中间件:dispatch(action) => reducer
使用中间件:dispatch(action) => 执行中间件代码 => reducer
- 中间件整理 https://blog.csdn.net/m0_62118859/article/details/124490882
react-thunk的原理
支持action可以是对象也可以是函数
使用步骤:
- 安装:yarn add redux-thunk
- 导入 redux-thunk
- 将 thunk 添加到 applyMiddleware 函数的参数(中间件列表)中
- 创建函数形式的 action,在函数中执行异步操作
// 导入 thunk 中间件
import thunk from 'redux-thunk'
// 将 thunk 添加到中间件列表中
// 知道:如果中间件中使用 logger 中间件,logger 中间件应该出现在 applyMiddleware 的最后一个参数
const store = createStore(rootReducer, applyMiddleware(thunk, logger))
原理(借助原码分析):
- 判断 action 的类型是不是函数,如果是函数,就调用该函数(action),并且传入了 dispatch 和 getState
- 如果不是函数,就调用下一个中间件(next),将 action 传递过去
- 如果没有其他中间件,那么,此处的 next 指的就是:Redux 自己的 dispatch 方法
function createThunkMiddleware(extraArgument) {
// Redux 中间件的写法:const myMiddleware = store => next => action => { /* 此处写 中间件 的代码 */ }
return ({ dispatch, getState }) => (next) => (action) => {
// redux-thunk 的核心代码:
// 判断 action 的类型是不是函数
// 如果是函数,就调用该函数(action),并且传入了 dispatch 和 getState
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
// 如果不是函数,就调用下一个中间件(next),将 action 传递过去
// 如果没有其他中间件,那么,此处的 next 指的就是:Redux 自己的 dispatch 方法
return next(action);
};
}
// 所以,在使用了 redux-thunk 中间件以后,那么,redux 就既可以处理 对象形式的 action 又可以处理 函数形式的 action 了
// 1 处理对象形式的 action
dispatch({ type: 'todos/clearAll' }) // 对应上面第 14 行代码
// 2 处理函数型的 action
export const clearAllAsync = () => {
return dispatch => {
// 在此处,执行异步操作
setTimeout(() => {
// 异步操作完成后,如果想要修改 redux 中的状态,就必须要
// 分发一个 对象形式的 action(同步的 action)
dispatch({ type: types.CLEAR_ALL })
}, 1000)
}
}
dispatch(clearAllAsync()) // 对应上面第 8、9 行代码
口述利用中间件打一个日志
步骤:
- 安装:yarn add redux-logger
- 导入 redux-logger 中间件
- 从 redux 中导入 applyMiddleware 函数
- 调用 applyMiddleware() 并传入 logger 中间件作为参数
- 将 applyMiddleware() 调用作为 createStore 函数的第二个参数
- 然后,调用 store.dispatch() 查看 console 中 logger 中间件记录的日志信息
import { createStore, applyMiddleware } from 'redux'
import logger from 'redux-logger'
import rootReducer from './reducers'
const store = createStore(rootReducer, applyMiddleware(logger))
redux的hook
在函数组件中,需要使用第三方的hook来完成状态机获取
useDispatch:产生一个disptach对象派发action
useSelector:作用类似于mapStateToProps,获取到状态机state对象,对数据进行刷选
官方提供的hook:useState、useEffect、useRef、useMemo、useCallback(扩展)
第三方提供:useHistory、useParams、useLocation、useSelector、useDispatch
useReducer的使用场景
useReducer 实际上是 useState 的升级版,都是用来存储和更新 state,只是应用的场景不一样。
一般情况下,我们使用 useState 就足够项目需要了,不多当遇到以下场景时,使用useReducer 会更好些
- 状态逻辑复杂:当状态的更新逻辑比较复杂时,使用 useReducer 可以将这个逻辑封装在 reducer 函数中,使代码更加清晰易懂
- 多组件共享状态:当多组件需要共享一个状态时,可以将这个状态放在父组件,然后通过 useReducer 将状态和更新函数传递给子组件,从而实现状态共享
- 需要处理连续的多个状态更新:当需要连续处理多个状态更新时,使用 useReducer 可以帮助我们更好地管理状态的变化和更新
微前端解决了什么问题(增量升级)
- 业务模块耦合严重
- 团队之间并行开发遇到困难
- 系统更新牵一发动全身,拆分为微应用可以达到团队自治,独立迭代
好处:独立开发、独立部署、独立运行、集成灵活、解耦、增量升级【不用死记硬背,重在独立和迭代方便,增量更新,解耦】
微前端的实现方式
常见的如:容器化:iframe, 微应用化:【Single-Spa,qiankun(基于Single-Spa,阿里系开源微前端框架)】,应用组件化:借助于Web Components技术,来构建跨框架的前端应用
还有什么路由分发(反向代理),前段微服务化,微件化这些了解概念即可
这个里里面说的很多,记常用的,自己总结几个一记哈
- 参考:17个可以实现微前端的方案:https://www.jianshu.com/p/0ac8e1a666cf
模块联邦的缺点(模块更新上)【存疑,模块更新上是什么意思】
模块联邦并不是完美的. 正如上面所说, 目前来看模块联邦只是NPM形式的拓展, 它依然有着它的缺陷.
例如, 模块联邦并没有样式隔离机制, 这意味着, 当主子应用很有可能会互相造成样式污染.
不同技术栈传递的模块,这种模块是无法通用的,需要通过某种手段去转换成本技术栈可使用的模块才可以
css实现透明度的方式
- rgba 设置背景色
background-color:rgba(0,152,50,0.7);// -->70%的不透明度
background-color:transparent;支持完全透明
- 使用opacity属性(指定不透明度,从0.0(完全透明)到1.0(完全不透明))
- 设置filter:opacity(%)样式设置图片的透明度
filter的使用:https://blog.csdn.net/Aria_Miazzy/article/details/128454697
算法:开平方跟(整数,小数)