关于面试:前端面试宝典react核心知识篇

41次阅读

共计 13615 个字符,预计需要花费 35 分钟才能阅读完成。

前言:

想零碎学习前端面试题,强烈推荐浏览 在线电子书(反对手机版,不断更新)。

本书特点:零碎全面(涵盖前端核心技术点),简洁,针对性强(针对面试场景设计)。

欢送在 github 上留言反馈

react 如何实现 keep-alive?

Keep-alive 是缓存路由应用的,保留之前路由的状态

实现办法:

  1. 应用 npm 库:

    1. react-router-cache-router
    2. React-activation

react 错误处理?

次要的 api(生命周期):

  • componentDidCatch(error,errorInfo): 同样能够将谬误日志上报给服务器
  • getDerivedStateFromError(error):更新 state 使下一次渲染可能显示降级后的 UI

注意事项:

  • 仅可捕捉其子组件的谬误,无奈捕捉其本身的谬误

你有应用过 suspense 组件吗?

动静加载(异步组件)加载时会有提早,在提早期间能够将一些内容展现给用户,比方:loading

(react16.6 新增的 API)

const resource = fetchProfileData();

function ProfilePage() {
  return (<Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // 尝试读取用户信息,只管该数据可能尚未加载
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // 尝试读取博文信息,只管该局部数据可能尚未加载
  const posts = resource.posts.read();
  return (
    <ul>
      {posts.map(post => (<li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}

参考资料:

何为 Suspense?

怎么动静导入组件,按需加载,代码宰割?

只有当组件被加载时,对应的资源才会导入

  • react-loadable: npm 库 按需加载
  • react.lazy: 原生反对(新版本 16.6),配合 suspense 一起应用,还要 webpack code splitting
  • require(component) : 在特定条件下,动静引入

react Context 介绍?

次要 api:

  • react.createContext : 创立 store
  • [store].Provider: 包裹组件,并通过 value 字段传递参数
  • [store].Consumer: 获取包裹组件内容

创立过程:

  1. 【创立 store】:通过 React.createContext 创立 AppContext 实例
  2. 【包裹整个组件】:应用 AppContext.Provider 组件
  3. 【注入全局变量】,在 AppContext.provider 组件上
  4. 【引入全局变量】:通过 AppContext.Consumer 组件,子组件的回调,获取 store 中的内容和办法

为什么 react 并不举荐咱们优先思考应用 context?

  • 【实验性】context 目前还处于试验阶段,可能会在前期有大扭转,防止给将来降级带来麻烦
  • 【稳定性】context 的更新须要通过 setState 触发,然而这并不是牢靠的。context 劫持跨组件拜访,然而,如果两头子组件通过一些办法不响应更新,比方 shouldComponentUpdate 返回 false,那么不能保障 context 的更新肯定达应用 context 的子组件。因而,context 的可靠性须要关注。不过是更新的问题,在新版的 APP 中得以解决

只有你能确保 context 是可控的,正当应用,能够给 react 组件开发带来弱小体验

render 函数中 return 如果没用应用 () 会用什么问题吗?

论断:如果换行就有问题

起因:babel 会将 jsx 语法编译成 js,同时会在每行主动增加分号(;), 如果 return 换行了,那么就变成了 return; 就会导致报错

  // 这样会报错,react
  class App extends React.Component{render(){
            return 
            <div>111</div>
        }
    }

介绍下渲染属性 render props?

性能:给纯函数组件加上 state, 响应 react 的生命周期

长处:hoc的毛病 render prop 都能够解决

  • 扩展性限度:hoc 无奈从内部拜访子组件的 state, 因而无奈通过 shouldComponentUpdate 过滤掉不必要的更新,react 在反对 es6 class 之后提供了 react.PureComponnet 来解决这个问题
  • ref 传递问题:ref 被隔断,起初的 react.forwardRef 来解决这个问题
  • Wrapper Hell(多层包裹):多层包裹,形象减少了复杂度和了解老本
  • 命名抵触:屡次嵌套,容易笼罩老属性
  • 不可见性:hoc 相当于黑盒

毛病:

  • 应用繁琐:hoc 复用只需借助装璜器语法(decorator)一行代码进行复用,render props 无奈做到如此简略
  • 嵌套过深:render props 尽管解脱了组件多层嵌套的问题,然而转化为了函数回调的嵌

参考资料:

React 中的 Render Props

React 如何进行组件 / 逻辑复用?

  • HOC(高阶组件)
    • 属性代理
    • 反向继承
  • 渲染属性(render props)
  • react-hooks
  • Mixin (已废除,不探讨)

PureComponent 组件介绍?

当 props/states 扭转时,PureComponent 会对它们进行浅比拟,起到性能优化的作用;

相当于在 component 组件的 shouldComponentUpdate 办法中进行了比拟才渲染

特地阐明:

  • 援用对象的数据倡议不要应用 PureComponnet 组件,否则会有坑

JSX 实质是什么?

JSX 应用 js 的模式来写 html 代码

jsx 自身是语法糖,无奈间接被浏览器解析,须要通过 babel 或者 typescript 来转换成 js。

许多蕴含预配置的工具,例如:create- react app 和 next.js 在其外部也引入了 jsx 转换。

旧的 JSX 转换会把 jsx 转换为 React.createElement 调用。

jsx 调用 js 自身的个性来动态创建 UI,与于传统模式下的模板语法不同

react 中组件通信的几种形式?

react 组件之前通信次要要四种形式

  • 父子组件:props,props 回调
  • 兄弟组件:独特父级,再由父节点转发 props,props 回调
  • 跨级组件:context 对象,注入全局变量:getChildContext; 获取全局变量:this.context.color;
  • 非嵌套组件:应用 事件订阅,向事件对象增加监听器,和触发事件来实现组件之间的通信,通过引入 event 模块实现
  • 全局状态管理工具:Redux,Mobox 保护全局 store

react UI 组件和容器组件的区别与利用?

容器组件:领有本人的状态,生命周期

UI 组件:只负责页面 UI 渲染,不具备任何逻辑,性能繁多,通常是无状态组件,没有本人的 state, 生命周期。

react 生命周期?

react 生命周期支流的次要有 2 个大的版本;

一个是 v16.3 之前的:

一个是 v16.3 之后的;

v16.3 之前 的生命周期次要分为 4 个阶段,8 个生命周期:

  • 初始化值阶段 initialization:getDefaultProps,getInitialState;
  • 初始阶段 mount:componentWillMount,componentDidMount;
  • 更新阶段 update:componetWillReceiveProps ,shouldComponetUpdate ,componentWillUpdate,
  • 销毁阶段 unmount:componetWillUnmount;

v16.3 之后的生命周期:

新引入了两个生命周期:

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

提醒 3 个不平安的生命周期(在 v17 中要被删除)

  • componentWillMount
  • componentWillReceiveProps
  • componetWillUpdate

新的命令周期:

React 的申请放在 componentWillMount 有什么问题?

错误观念:componentWillMount 中能够提前进行异步申请,防止白屏工夫;

剖析:componentWillMount 比 componentDidMount 相差不了多少微秒;

问题

  • 在 SSR(服务端渲染)中,componentWillMount 生命周期会执行两次,导致多余申请
  • 在 react16 进行 fiber 重写后,componentWillMount 可能在一次渲染中屡次调用
  • react17 版本后要删除 componentWillMount 生命周期

目前官网举荐异步申请在 componentDidMount

create-react-app 有什么长处和毛病?

长处:

疾速生成架手架

毛病:

  1. 默认不引入 polyfill, 须要在入口引入 babel-polyfill
  2. 默认只反对 css 热加载,不反对 html,js 热加载(举荐应用:react-hot-loader)

介绍下 Immutable?

Immutable 是一种不同变的数据类型,数据一旦被创立,就不能更改的数据,每当对它进行批改,就会返回新的 immutable 对象,在做对象比拟时,能晋升性能;

实现原理:

immutable 实现原理是长久化数据结构,构造共享,防止对数据对象进行深拷贝;

react、vue 有什么区别?

区别 react vue
模板引擎 JSX,更多灵便,纯 js 语法(能够通过 babel 插件实现模板引擎) vue template, 指令,更加简略(vue 也能够应用 jsx 语法)
复用 Mixin->Hoc->render props->hook Mixin-> slot->Hoc(比拟用,模板套模板,奇怪做法)-> vue3.0 function baseed APi
性能优化形式 手动优化:PureComponent/shouldComponentUpdate 主动优化:准确监听数据变动
监听数据变动的实现原理 手动:通过比拟援用的形式(diff) 主动:getter/setter 以及一些函数的劫持(当 state 特地多的时候,当 watcher 也会很多,导致卡顿)
数据流 数据不可变,单向数据流,函数式编程思维 数据可变,双向数据绑定,(组件和 DOM 之间的),响应式设计
设计思维 all in js (html->jsx, css->style-component/jss) html,,css,js 写在一个文件中,应用各自的形式
性能内置 少(交给社区,reactDom,propType) 多(使用方便)
长处 大型项目更适合 兼容老我的项目,上手简略

数据流比照:

react 数据更改逻辑:

vue 数据更改逻辑:

参考资料:

Vue 和 React 的长处别离是什么?

集体了解 Vue 和 React 区别

Vue 与 React 的区别之我见

让 react 反对 vue 的 template 语法如何实现?

基于形象语法树 AST,实现解析模板指令的插件(应该是实现一个 babel 插件,因为 jsx 解析成 js 语法,是通过 babel 解析的)

对 react 的认识,它的优缺点?

长处:

  1. 提供了申明式的编程思维
  2. 提供了组件化的开发思维,大大提高前端开发的效率
  3. 引入了虚构 dom 的概念,使得 react 能够跨端进行类各界面开发,react native,react vr,ssr;
  4. 引入了 diff 算法,进步了渲染效率

有余:

  1. 侵入性强,对老代码只能重做,不能局部集成(比方 vue);

jsx 语法有什么特点相比 js?

jsx 以 js 为核心来写 html 代码

jsx 语法特点:

  1. 反对 js+html 混写;
  2. jsx 编译更快比 html

长处:jsx 类型平安的,在编译过程中就能发现错误;

create-react-app 如何实现,蕴含哪些内容,如何自定义一个脚手架?

定义:create-react-app 是一个疾速生成 react 我的项目的脚手架;

长处:

  • 无需设置 webpack 配置

毛病:

  • 暗藏了 webpack,babel presets 的设置,批改起来比拟麻烦

HOC

什么是高阶函数?

如果一个函数,承受一个或多个函数作为参数或者返回一个函数 ,就可称之为 高阶函数

特点:

  • 是函数
  • 参数是函数
  • or 返回是函数

eg: array 对象中的 map,filter,sort 办法都是高阶函数

  function add(x,y,f){return f(x)+f(y)
  }

  let num=add(2,-2,Math.abs)
  console.log(num);

什么是高阶组件?

高阶组件就是一个函数(react 函数组件),接管一个组件,解决后返回的新组件

高阶组件是高阶函数的衍生

外围性能:实现形象和可重用性

它的函数签名能够用相似 hashell 的伪代码示意

  • W(WrappedComponent)被包裹的组件,当传参数传入 hoc 函数中
  • E(EnhancedComponent)返回的新组件
hocFactory:: W: React.Component => E: React.Component

高阶组件,不是真正意义上的组件,其实是一种模式;

能够对逻辑代码进行抽离,或者增加某个共用办法;

高阶组件是装璜器模式在 react 中的实现

主要用途:

  • 代码重用,逻辑和疏导形象
  • 渲染劫持
  • 状态形象和管制
  • Props 管制

参考资料:React 中的高阶组件及其利用场景

hoc 存在的问题?

一、静态方法失落

二、refs 属性不能透传

三、反向继承不能保障残缺的子组件树被解析

hoc 高阶组件应用场景?

react-redux:connect 就是一个高阶组件, 接管一个 component, 并返回一个新的 componet, 解决了监听 store 和后续的解决;

react-router:withrouter 为一个组件注入 history 对象;

你在我的项目中怎么应用的高阶组件?

不谈场景的技术都是在耍流氓

  • 权限管制:// 也能够在 history 路由切换的时候,加个监听办法,在顶层做监听解决,不过页面会闪一下

    • 页面级别:withAdminAuth(Page),withVIPAuth(Page)
    • 页面元素级别:
  • 组件渲染性能追踪
  • 页面复用
  • 全局常量(通过接口申请),能过 hoc 抽离 // 也能够通过全局状态治理来获取
  • 对以后页面的一些事件的默认执行做阻止(比方:阻止 app 的默认下拉事件)

参考资料:

React 中的高阶组件及其利用场景

高阶组件和父组件的区别?

高阶组件能够重写传入组件的 state,function,props; 能够对代码逻辑进行抽离,重写;

父组件只是管制子组件的 view 层;

hook

hooks 原理剖析,如何实现?

参考:

[[译] 深刻 React Hook 零碎的原理](https://juejin.cn/post/684490…

hooks 与 react 生命周期的关系?

hooks 组件有生命周期,函数组件没有生命周期

hooks 的生命周期其实就是:

  • useState
  • useEffect
  • useLayoutEffect

//hooks 模仿生命周期函数,与 class 的生命周期有什么区别

react hook 优缺点?

react hook 是 v16.8 的新个性;

传统的纯函数组件,

react hooks 设计目标,加强版的函数组件,齐全不应用‘类’,就能写出一个全功能的组件,不能蕴含状态,也不反对生命周期),hook 在无需批改组件构造的状况下复用状态逻辑;

劣势:

  • 简洁:react hooks 解决了 hoc 和 render props 的嵌套问题,更加简洁(在不应用 class 的状况下,应用 state 及 react 其余个性(省的把纯函数组件 / 其余组件改来改去))
  • 解耦:react hooks 能够更不便地把 UI 和状态拆散,做到更彻底的解耦
  • 组合:hooks 中能够援用另外的 hooks 造成新的 hooks,组合变幻无穷
  • 函数敌对:react hooks 为函数组件而生,解决了类组件的几大问题

    • 解决了 this 的指向问题
    • 让组件更好的复用(老的 class 组件简短、蕴含本身的状态 state)
    • 让 react 编程格调更取向函数式编程格调,应用 function 代替 class

毛病(坑):

  • 【useState 数组批改】应用 useState 批改 array 的值时,不要应用 push/pop/splice 等间接更改数据对象的办法,否则无奈批改,应该应用解构或其余变量代替
  • 【hook 执行地位】不要在循环、条件、嵌套中调有 hook,必须始终在 react 函数顶层应用 Hook,这是因为 react 须要利用调用程序来正确更新相应的状态,以及调用相应的钩子函数,否则会导致调用程序不一致性,从而产生难以预料到的结果
  • 响应式的 useEffect:当逻辑较简单时,可触发屡次
  • 状态不同步:函数的运行是独立的,每个函数都有一份独立的作用域。函数的变量是保留在运行时的作用域外面,当咱们有异步操作的时候,常常会碰到异步回调的变量援用是之前的,也就是旧的(这里也能够了解成闭包场景可能援用到旧的 state、props 值),心愿输入最新内容的话,能够应用 useRef 来保留 state
  • 毁坏了 pureComponent、react.memo 浅比拟的性能优化成果(为了取最新的 props 和 state, 每次 render 都要从新创立事件处函数)
  • react.memo 并不能齐全代替 shouldComponentUpdate(因为拿不到 state change , 只针对 props change)

参考资料:
hooks 中的坑,以及为什么?

hooks 注意事项?

  • 不同 hook 中,不要应用判断(if)

react hook 底层是基于链表(Array)实现,每次组件被 render 时,会按程序执行所有 hooks, 因为底层是链表,每个 hook 的 next 指向下一个 hook,所有不能在不同 hooks 调用中应用判断条件,因为 if 会导致程序不正确,从而导致报错

// 谬误示例
function App(){const [name,setName]=useState('xz');
// 这里不能应用 if 判断
if(configState){const [age,setAage]=useState('0')
}
}

react hooks 异步操作注意事项?

一、如何在组件加载时发动异步工作

二、如何在组件交互时发动异步工作

三、其余陷阱

参考资料:

React Hooks 异步操作踩坑记

react hooks API 有哪些?

hooks(实质是一类非凡的函数,能够为函数式注入一些非凡的性能)的次要 api:

根底 Hook:

  • useState : 状态钩子,为函数组件提供外部状态
  • useEffect:副作用钩子,提供了相似于 componentDidMount 等生命周期钩子的性能
  • useContext:共享钩子,在组件之间共享状态,能够解决 react 逐层通过 props 传递数据;

额定的 Hook:

  • useReducer: action 钩子,提供了状态治理,其基本原理是通过用户在页面上发动的 action,从而通过 reduce 办法来扭转 state,从而实现页面和状态的通信,应用很像 redux
  • useCallBack:把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项扭转时才会更新
  • useMemo:把 ”” 创立 ”” 函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项扭转时从新计算,能够作为性能优化的伎俩。
  • useRef:获取组件的实例,返回一个可变的 ref 对象,返回的 ref 对象在组件的整个生命周期内放弃不变
  • useLayoutEffect:它会在所有 DOM 变更后同步调用 effect
  • useDebugValue

demo:

//useMemo 
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

//useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);

参考资料:Hook API 索引

useEffect 介绍?

useEffect 能够让你在函数组件中执行副应用(数据获取,设置订阅,手动更改 React 组件中的 DOM)操作

默认状况下每次函数加载完,都会执行(不要在此批改 state,防止循环调用),useEffect 相当于是 class 组件中的 componentDidMount,componentDidUpdate,componentWillUnMount 三个函数的组合

参数阐明:

  • 参数一:

    • type:function
    • 执行的函数
  • 参数二(可选):监听值

    • type:array
    • 要监听的值(当监听值扭转才执行,如果只想执行一次能够传一个[]):如果值没有扭转,就不必执行 effect 函数,能够传入监听的值

      • return callBack: 清理函数,执行有两种状况

        • componentWillUnmount
        • 在每次 userEffect 执行前(第二次开始)

分类:

一)不须要革除

react 更新 DOM 之后运行的一些额定代码,操作实现即可疏忽

应用场景:

  • 手动变更 DOM(批改 title)
  • 记录日志
  • 发送埋点申请

二)须要革除

effect 返回一个函数,在革除时调用(相当于 class 中 componentWillUnmount 生命周期)

因为增加 / 删除订阅代码的紧密性,所以 useEffect 设计在同一个中央,如果 effect 返回一个函数,react 将会在执行革除时调用它

应用场景:

  • 订阅内部数据源(避免数据泄露)
  • 设置页面题目,返回重置原题目

useEffect 和 useLayoutEffect 区别?

  • useEffect 相比 componentDidMount/componentDidUpdate 不同之处在于,应用 useEffect 调度的 effect 不会阻塞浏览器更新屏幕,这让利用响应更快,大多数据状况下,effect 不须要同步地执行,个别情况下(例如测量布局),有独自的 useLayoutEffect hook 可应用,其 API 与 useEffect 雷同
  • useEffect 在副应用完结之后,会提早一段时间执行,并非同步执行。遇到 dom 操作,最好应用 userLayoutEffect
  • userLayoutEffect 外面的 callback 函数会在 DOM 更新实现后立刻执行,然而会在浏览器进行任何绘制前运行实现,阻塞了浏览器的绘制

useContext 介绍?

共享状态钩子,在组件之间共享状态,能够解决 react 逐层通过 props 传递数据的问题

应用流程(应用流程和 react-redux 差不多):

  1. 创立 store:通过 createContext Api
  2. 包裹整个组件:通过 store 中的 Provider 办法
  3. 注入全局变量,provider 组件中
  4. 引入全局变量:通过 useContext, 传入 store 的名字,返回一个 store 对象内容
    const {useState, createContext, useContext} = React;

    function App(){
        // 创立 store
        const AppContext=createContext({});

        function A(){
            // 从 store 中取值
            const {name}=useContext(AppContext);
            return <div>A 组件 Name:{name}</div>
        }

        function B(){
            // 从 store 中取值
            const {name}=useContext(AppContext);
            return <div>B 组件 Name:{name}</div>
        }

        // 在顶层包裹所有元素,注入到每个子组件中
        return (<AppContext.Provider value={{name:'xz'}}>
                <A/>
                <B/>
            </AppContext.Provider>
        )
    }

    ReactDOM.render(
        <App />,
        document.getElementById('app')
    );

参考资料:

React Hooks 罕用钩子及基本原理

useReducer 介绍?

action 钩子,提供了状态治理

实现过程(和 redux 差不多,但无奈提供中间件等性能):

  1. 用户在页面上 发动 action(通过 dispath 办法)
  2. 从而通过 reducer 办法 来扭转 state, 从而实现 页面和状态的通信

如何创立本人的 hooks?

实现步骤:

  1. 定义一个 hook 函数,并返回一个数组(外部能够调用 react 其余 hooks)
  2. 从自定义的 hook 函数中取出对象的数据,做业务逻辑解决即可

useCallBack 介绍?

useState 介绍?

useState 是一个内置的 React Hook。useState(0) 返回一个元组,其中第一个参数 count 是计数器的以后状态,setCounter 提供更新计数器状态的办法。

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {setCounter(count + 1);
    setMoreStuff(...);
    ...
};

Fiber

什么是 Fiber?是为了解决什么问题?

react fiber 是一种基于浏览器的 单线程调度算法

react 算法的扭转(Fiber 实现的原理):

  • 16 版本之前:reconcilation 算法实际上是递归,想要中断递归是很艰难的
  • 16 版本之后:开始应用循环来代替之前的递归

fiber:一种将 recocilation(递归 diff),拆分成无数据个小工作的算法;它随时可能进行,复原。进行复原的机会取决于以后的一帧(16ms)内,还有没有足够的工夫容许计算

fiber 是 react16 中新公布的个性;

解决的问题:

react 在渲染过程时,从 setState 开始到渲染实现,两头过程是同步;

如果渲染的组件比拟大,js 执行会长工夫占有主线程,会导致页面响应度变差,使得 react 在动画,手势等利用中成果比拟差;

实现过程及原理(核心理念就是:time slicing):

  1. 拆分:把渲染过程进行拆分成多个小工作
  2. 查看:每次执行完一个小工作,就去对列中查看是否有新的响应须要解决
  3. 继续执行:如果有就执行优化及更高的响应事件,如果没有继续执行后续工作

refs

react 的 refs 有什么用,应用场景?

react 次要提供了一种规范数据流的形式来更新视图;

然而页面某些场景是脱离数据流的,这个时候就能够应用 refs;

react refs 是用来获组件援用的, 取后能够调用 dom 的办法;

应用场景

  • 治理焦点、抉择文本或者媒体播放时,获取焦点 this,refs.inputPhone.focus();
  • 触发式动画
  • 与第三方 DOM 库整合

refs 注意事项:

不能在无状态组件中应用 refs

Virtual DOM

什么是 Virtual DOM,它的长处?

Virtual DOM 是对 DOM 的形象,实质是 js 对象,这个对象就是更加轻量级对 DOM 的形容

长处:

  • 【性能优化】操作实在 DOM 慢,频繁变动 DOM 会造成浏览器回流 / 重绘,虚构 DOM 形象的这一层,在 patch(batching 批处理)过程中尽可能地一次性将差别更新到 DOM 中,升高更新 DOM 的频率
  • 【数据驱动程序】应用数据驱动页面,而不是操作 DOM 的模式
  • 【跨平台】:node 层没有 DOM, 然而 react 却能够在 node 层(SSR)运行

能够通过 chrome 的 console 面板中的

参考资料:

虚构 DOM 原理

Virtual DOM 的创立,更新,diff 过程?

虚构 DOM 的创立

虚构 DOM 是对实在 DOM 的形象,依据不同的需要,能够做出不同的形象,比拟 snabbdom.js 的形象形式

根本构造

  /*
    * 虚构 DOM 实质是一个 JS 对象,这个对象是更加轻量级的对 DOM 的形容
    * */
    
    //tagName,props,children
    const element={
        tagName:'ul',
        props:{id:'list'},
        children: [{
            tagName:'li',
            props:{class:'item'},
            children:['item1']  //item1 只是没有包裹的子节点
        }]
    }

react diff 介绍?

传统的页面更新,是间接操作 dom 来实现的,比方原生 js 或者 jquery,然而这种形式性能开销比拟大;

react 在初始化的时候会生成一个虚构 dom, 每次更新视图会比拟前后虚构 dom 的区别;

这个比拟办法就是 diff 算法,diff 算法很早就曾经呈现了;然而 react 的 diff 算法有一个很大区别;

react diff 算法劣势:

传递 diff 算法

  • 遍历模式:循环递规 对节点进行顺次比照
  • 工夫算法复杂度:o(n^3)次方,n 代表节点数

react diff 算法

  • 遍历模式:采纳 逐层比拟 的形式(DOM 的特点,个别很少呈现跨层级的 DOM 变更)
  • 工夫算法复杂度:O(n)次方;

目前社区里的两个算法库:

  • snabbdom.js(双端比拟算法):v2.0 借鉴
  • inferno.js(速度更快):vue3.0 借鉴

    • 核心思想:利用 LIS(最长递增序列)做动静布局,找到最小的挪动次数

react 算法 PK inferno.js

  • react diff:

    1. 把 a,b,c 挪动到他们相应的地位
    2. 再 + 1 共三步操作
  • inferno: 间接把 d 挪动到最后面,一步到位
A:[a,b,c,d]
B:[d,a,b,c]

同层比拟

参考资料:

diff 算法原理概述

setState

setState 之后产生了什么?

  1. 【数据合并】多个 setState 会进行数据合拼,筹备批量更新
  2. 【数据合并到组件的以后状态】生成新的 react tree
  3. 【更新 UI】比拟应用 diff 算法,比拟新旧 virtual dom,,最小化 DOM 操作
  4. 【执行回调函数】setState 第二个参数

setState 到底是同步还是异步?

论断:有时体现出同步,有时体现出“异步“

体现场景:

  • 同步:setTimeout,原生事件;
  • 异步:合成事件,钩子函数(生命周期);

react 异步阐明:

setState 异步并不是说外部代码由异步代码实现,其实自身执行过程和代码都是同步的,只是合成事件和钩子函数的调用程序在更新之前;在异步更新中,屡次 setState 前面的值会笼罩后面的;

为什么 setState 不设计成同步的?

  • 放弃外部的一致性,和状态的安全性

放弃 state,props.refs 一致性;

  • 性能优化

react 会对根据不同的调用源,给不同的 setState 调用调配不同的优先级;

调用源包含:事件处理、网络申请、动画;

  • 更多可能性

异步获取数据后,对立渲染页面;放弃一致性,

react 事件

react 事件机制?

一、事件注册

  • 【组件装载】装载 / 更新
  • 【事件注册与卸载】能过 lastPropsnextProps 判断是否有新增、删除事件别离调用事件注册、卸载办法
  • 【事件存储】能过 eventPluginHub, enqueuePutListener 进行事件存储
  • 【获取 document 对象】
  • 【事件冒泡 / 捕捉】依据事件名称(onClick,onCaptureClick)判断
  • 【事件监听】:addEventListener,addachEvent(兼容 IE)
  • 【注册原生事件】给 document 注册原生事件回调为 dispatchEvent (对立的事件散发机制)

二、事件存储

{
onClick:{fn1:()=>{}
 fn2:()=>{}
},
onChange:{fn3:()=>{}
 fn4:()=>{}
}
}

三、事件触发 / 执行

 事件执行程序(原生事件与合成事件)
  1. dom child

    1. dom parent
    1. react child
    2. react parent
    3. dom document

四、合成事件

  1. 【调用 EventPluginHub】的 extractEvents 办法
  2. 【遍历所有 EventPlugin】用来解决不同事的工具办法
  3. 【返回事件池】在每个 EventPlugin 中依据不同的事件类型返回
  4. 【取出合成事件】从事件池中取出,如为空,则创立
  5. 【取出回调函数】依据元素 nodeid(惟一标识 key) 和事件类型 从 listenerBink 中取出 回调函数
  6. 【返回合成事件】返回带有合成事件参数的回调函数

参考资料:

【React 深刻】React 事件机制

react 事件与原生事件的区别?

语法区别:

  • 【事件名小驼峰】react 事件命令采纳小驼峰式,而不是纯小写
  • 【事件办法函数】应用 JSX 语法时,你须要传入一个函数作为事件处理函数,而不是一个字符串

react 事件的长处

  • 【兼容性更强】合成事件:react 事件对生成事件进行了包装,解决了浏览器兼容性问题(阻止浏览器默认行为,阻止冒泡)

react 事件与原生事件的执行程序?

  1. 原生事件,顺次冒泡执行
  2. react 合成事件,顺次冒泡执行
  3. document 事件执行
  /*
     * 执行后果:* 1. dom child
     * 2. dom parent
     * 3. react child
     * 4. react parent
     * 5. dom document
     * */

react 事件与原生事件能够混用吗?

react 事件与原生事件最好不要混用

起因:

  • 原生事件如果执行 stopProagation 办法,则会导致其余 react 事件生效,因为所有元素的事件将无奈冒泡到 document 上

react-router

React-Router 怎么设置重定向?

应用 重定向 Api : Redirect

正文完
 0