乐趣区

关于前端:前端面试资料整理React篇

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 然而会引起刷新

退出移动版