React
参考
React 源码
react 为什么实用 JSX?
萝卜青菜各有所爱。
然而 react 团队认为模板计划不好:
- 模板拆散了技术栈,减少了技术点。
- 看起来像 html 的 jsx。
- react 规矩性太强,须要 jsx 来辅助
例如应用 vue 下面是 html 模板,上面是 js 逻辑从而造成一个组件性能。然而 react 将 html 和运行逻辑都运行在一个 class。
JSX 映射虚构 DOM 的原理?
JSX 是 creatElement 的语法糖,应用的是 babel 的本义器,理论是通过两个办法实现,一个是 creatElement,一个 reactElement
// 定义一个 react 对象
reactElement(type, key, ref, self, source, ReactCurrentOwner.current, props)
Rreact 数据流治理
数据驱动视图?UI = render(data)
data 与 state 的区别是什么?
状态(state)与数据(data),组件中的通信就是 data 的通信,react 外围就是对数据的治理
数据流动:
- 父 -> 子
- 子 -> 父
- 兄弟
- 无关系
单向数据流
MVC 的劣势双向数据流。引起凌乱。
Action -> Dispatcher -> Store -> View
|-------<------Action<-|
ACTION 视图层发送的音讯
redux 是 js 的状态容器
Action -> Reducer -> Store[state, state]
|-------<------View--<-|
redux 优缺点
毛病:
- 应用流程简单。
- state 不会随着组件销毁,状态残留。
- 频繁更新 store 时,会更加卡顿。
- 不反对 ts。
mobx
原理是利用 es6 proxy 数据劫持,不会想 redux 应用简单。
React Fiber
超过 16 毫秒后会掉帧。
原来的 React 是通过利用 js 的执行栈,始终执行到栈空地位。新版的 React 保护了本人的执行栈,通过链表的模式,遍历树形构造,优化了执行过程。
参考
虚构 DOM 和 diff 算法
虚构 DOM
React 渲染 dom 的一种优化伎俩,其原理是利用 createFragment,即“发明碎片”。所有的 DOM 操作都将在“碎片”中操作,直到操作实现,再一起渲染。
diff 算法
是 React 更新 dom 元素的一套算法,其核心思想是,比拟“节点树”的各个节点,依据比拟的后果来决定是否更新该节点。通过其优化伎俩,将更新树的工夫复杂度从 O(n^3)变为 O(n)。
diff 策略
- 疏忽跨组件的挪动操作
- 同类组件创立雷同树,不同类则创立不同类的数(React Component 和 function Component)
- 兄弟,key
分为 3 个更新策略 tree diff, component diff, element diff:
tree diff: 当遇到树形构造更新时,仅比拟同层节点,起子节点仅有创立和删除。这就象征这,如果存在挪动某个树形构造的两头节点,那么原树将间接删除该节点及其子节点,在新树中创立起节点及其子节点。另外,官网不倡议存在跨节点的挪动操作。
component diff: 当节点更新为不同类型的节点时,成为 dirty component,react 认为更新成不同类型的节点,其构造肯定是不一样的(树形构造),因而间接删除该节点后,间接创立。
element diff: 计算兄弟节点间接的挪动操作,由原来的将指标位节点删除再创立的更新策略,更改为通过标识 key,判断是为原来的节点,另外也取得了是否产生挪动操作的判断根据。
由此也得出了 3 条优化倡议:
- 设置 key
- 不要将组件更新为不同类型
- 缩小将兄弟组件从开端移至头部的操作
参考
Redux
待补充
React 优化
常见的优化细节:
- function 组件代替 class 组件 -> 为什么?参考 1 参考 2
- HOC
- 应用 redux 这类状态管理工具时,局部不专用的 state 不必挂载在 model 中 –> 为什么?
- 首屏优化计划
- lazy 懒加载组件
- react-router 的 loading 改善体验
- ssr (service side rendering)和 csr (client side rendering)
- pureComponent 和 shouldUpdate 优化更新频率
- componentDidCatch 探测谬误边界
- 通过 Fragment 缩小标签深度
- render 函数中的变量申明晋升到里面,缩小 GC
React-Hooks
useState 相当于 class component 中的 setState。
function render() {ReactDom.render(<App />, document.getElementById('root'))
}
function myState(initState) {
let state = initState
const update = (newState) => {
state = newState
render()}
return [state, update]
}
function App () {}
useEffect 相当于 class component 中的若干申明周期函数
为什么 16.8 退出 Hook?或者为什么减少 function component?
- class component 复用状态会很难。HOC 尽管解决了,然而有嵌套天堂的问题。
- class component 申明周期如果存在更改,其余生命周期可能均须要更改。
- es6 的 class 不如 function 对初学者更敌对
- this 的指向
官网答复
站在设计者的角度来思考。
SSR
next 次要是用在 React。
npx create-next-app
react-router
依据 history 开发的无刷新路由器。
次要有 3 个类型:hashHistory、borwerHistory、memoryHistory,罕用的是 hashHistory 和 browerHistory。
新版本是 react-router-dom,
import React from "react";
import {Router} from "react-router";
import {createBrowserHistory as createHistory} from "history";
import PropTypes from "prop-types";
import warning from "tiny-warning";
/**
* The public API for a <Router> that uses HTML5 history.
*/
class BrowserRouter extends React.Component {history = createHistory(this.props);
render() {return <Router history={this.history} children={this.props.children} />;
}
}
export default BrowserRouter;
区别
略
browerHistory 与 hashHistory 区别
hash 路由是是依据扭转 # 前面的锚点来刷新,通过 window.onhashChange 监听变动,从而依据路由处找到相应的文件
history 是通过 html5 的 window.history 这个 web API 来实现
hashHistory 的特点:
- 应用的是 history.location.hash 即 history.location.hash = “abc” (相当于是 localhost/#abc)
- 只能通过批改 # 前面的地址实现刷新
- 通过 window.onhashchange 监听 hash 变动,window.addEventListener(‘onhashchange’, hashchangeHandler)
- 不能想 window.history.go(-1) 这种形式,只能通过字符串扭转 url
- 对搜索引擎不敌对,且不好追踪
browerHistory 的特点:
- 应用的是 History 对象,提供 go, back, forward 的办法
- 雷同的 url 会产生更新,并且压入历史记录中
- 通过 push 和 replace 办法,理论是通过 pushState,replaceState 实现无刷新跳转。其中 pushState 会压入浏览器历史栈,即 History.length + 1,replaceState 则不会。
问题
应用 history 更新路由且失常渲染后,再刷新,会引起 404。(待验证)
是因为 history 更新了 url,也就是拜访地址,此时向后端服务器申请时,如果没有匹配地址的资源则会 404。
例如 nginx 配置 /test 地址拜访。通过 history router 从 /test 跳转至 /say,刷新时,服务器将找不到资源,能够通过配置父级门路躲避掉。
window.location 也会更改 url 然而会引起刷新