【温故知新】React 上

React

react 一个专注于构建用户界面的 JavaScript 库

  • virtual Dom 模型
    • 虚拟 dom 其实就是对真实 dom 的一个抽象,是一个 js 对象,react 所有的表层操作其实都是在修改 vdom
  • 生命周期管理
  • setState 机制
  • react patch、事件系统

jsx 如何转换为 js 的

  • 依靠 Babel 或 TypeScript 来将 JSX 代码转换为 JavaScript。许多包含预配置的工具,例如 Create React App 或 Next.js,在其内部也引入了 JSX 转换。
  • 当你使用 JSX 时,编译器会将其转换为浏览器可以理解的 React 函数调用。旧的 JSX 转换会把 JSX 转换为 React.createElement(…) 调用。
  • react 17 与 babel 合作,提供新的转换

React 中可以在 render 访问 refs 吗

  • 不可以,render 阶段 DOM 还没有生成,无法获取 DOM。DOM 的获取需要在 pre-commit 阶段和 commit 阶段

React 与 Vue 的 diff 算法有何不同

  • 自 React 16 起,引入了 Fiber 架构。
    为了使整个更新过程可随时暂停恢复,节点与树分别采用了 FiberNode 与 FiberTree 进行重构。
    fiberNode 使用了双链表的结构,可以直接找到兄弟节点与子节点。
    整个更新过程由 current 与 workInProgress 两株树双缓冲完成。
    workInProgress 更新完成后,再通过修改 current 相关指针指向新节点。
  • Vue 的整体 diff 策略与 React 对齐,虽然缺乏时间切片能力,
    但这并不意味着 Vue 的性能更差,因为在 Vue3 初期引入过,
    后期因为收益不高移除掉了。除了高帧率动画,在 Vue 中其他的场景几乎都可以使用防抖和节流去提高响应性能。

React 的状态提升是什么

  • 把共用的属性提升到共同父组件管理

props.children 和 React.Children 有什么区别

  • 在 React 中,当涉及组件嵌套,在父组件中使用 props.children 把所有子组件显示出来
  • React.Children.map 方法让我们对父组件的所有子组件又更灵活的控制。另外还有 foreach 等方法
  • JavaScript 中的 map 不会对为 null 或者 undefined 的数据进行处理,而 React.Children.map 中的 map 可以处理 React.Children 为 null 或者 undefined 的情况。

setState 是同步还是异步

  • 在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state 。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。
  • 原因:在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state
  • 注意: setState的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

说说 Render Props、HOC

  • HOC
    • HOC)是 React 中用于复用组件逻辑的一种高级技巧。
  • RenderProps
    • 指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术
    • 更具体地说,render prop 是一个用于告知组件需要渲染什么内容的函数 prop。
    • 优点:数据共享、代码复用,将组件内的 state 作为 props 传递给调用者,将渲染逻辑交给调用者。
    • 缺点:无法在 return 语句外访问数据、嵌套写法不够优雅

component 和 PureComponent 的区别

  • pureComponent 通过 prop 和 state 的浅比较(shallowEqual)来实现 shouldComponentUpdate
  • component 是需要开发者在 shouldComponentUpdate 钩子函数中自己写 render 逻辑的,在某些情况下可以使用 pureComponent 来提升性能。
  • pureComponent 的优点:不需要开发者使用 shouldComponentUpdate 就可使用简单的判断来提升性能;
  • pureComponent 的缺点:由于进行的是浅比较,可能由于深层的数据不一致导致而产生错误的否定判断,从而导致页面得不到更新;

function 和 class component 的区别

  • fun 没有实例,没有 this ,没有生命周期

  • class 生命周期执行顺序

    • 挂载:constructor() => static getDerivedStateFromProps() => render() => componentDidMount()

    • 卸载:componentWillUnmount()

    • 错误处理:static getDerivedStateFromError() componentDidCatch()

    • 更新:

      • static getDerivedStateFromProps()
      • shouldComponentUpdate()
      • render()
      • getSnapshotBeforeUpdate()
      • componentDidUpdate()

Hooks

对 React Hook 的理解,它的实现原理是什么

  • class Component,由于继承 React.Component,可以使用很多现成的东西,state 和 生命周期,但是这样也造成使用的繁琐,难以拆分和复用
  • function Component 由于没有实例,没有 this 无法维护 state,在 hooks 之前也被称为无状态组件。

useEffect 与 useLayoutEffect 的区别

  • 同步异步,防止首页闪屏

为什么第二个参数是空数组,相当于 componentDidMount ?

  • 因为依赖一直不变化,callback 不会二次执行。

setState 和 useState 区别

  • useState 和 this.setState 区别之处在于,前者每次更新后 state 都是新值,换而言之其实是不可变数据的概念。
    而后者使用后,其实更新 state 部分的值,引用本身并无改变。
  • useState 内部基于 useReducer 实现,方法返回 state 本身以及一个修改 state 的方法。
  • 通过 setXXX 修改数据,不会和 setState 一样进行对象属性合并,会直接覆盖。
  • Hooks 函数组件中,存在渲染闭包的概念,在一次渲染闭包中,state 是固定不变的。
  • Hooks 函数组件,默认开启 类 Object.is 的浅层比较,类似默认开启 PureComponent 的优化方式。

为什么只能在最外层使用 hooks

  • 官网:确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。
  • 因为底层存放 hooks 的是在 fiber 对象的 memoizedState 数组里按照 hooks 的定义顺序存入,每一个 hooks 的 next 都会指向下一个,如果 hooks 顺序变化,memoizedState 并不会感知

自定义的 Hook 是如何影响使用它的函数组件的?

  • 共享同一个 memoizedState,共享同一个顺序。

“Capture Value” 特性是如何产生的?

  • Capture Value 概念的解释:每次 Render 的内容都会形成一个快照并保留下来,因此当状态变更而 Rerender 时,
    就形成了 N 个 Render 状态,而每个 Render 状态都拥有自己固定不变的 Props 与 State。
  • 每一次 ReRender 的时候,都是重新去执行函数组件了,对于之前已经执行过的函数组件,并不会做任何操作。

React Hooks 在平时开发中需要注意的问题和原因

  • 必须始终在 React 函数的顶层使用 Hook
  • 使用 useState 时候,使用 push,pop,splice 等直接更改数组对象的坑(使用解构),this.setState 却没有问题。
  • useState 设置状态值通过 props 时,只有第一次生效,后期需要更新状态,必须通过 useEffect。
  • React.memo 等效于 PureComponent,它只浅比较 props。这里也可以使用 useMemo 第二个参数进行优化

React-Router

React-Router 的实现原理是什么?

  • 客户端路由实现的思想:
    • 基于 hash 的路由:通过监听 hashchange 事件,感知 hash 的变化,改变 hash 可以直接通过 location.hash=xxx
    • 基于 H5 history 路由: 改变 url 可以通过 history.pushState 和 resplaceState 等,会将 URL 压入堆栈,同时能够应用 history.go() 等 API 监听 url 的变化可以通过自定义事件触发实现
  • 基于 history 库来实现上述不同的客户端路由实现思想,并且能够保存历史记录等,磨平浏览器差异,上层无感知
  • 通过维护的列表,在每次 URL 发生变化的回收,通过配置的 路由路径,匹配到对应的 Component,并且 render

router 里 标签和 标签有什么区别

  • 从最终渲染的 DOM 来看,这两者都是链接,都是 标签,区别是: 是 react-router 里实现路由跳转的链接,一般配合 Route 使用, react-router 接管了其默认的链接跳转行为,区别于传统的页面跳转, 的“跳转”行为只会触发相匹配的 Route 对应的页面内容更新,而不会刷新整个页面。
  • 而 标签就是普通的超链接了,用于从当前页面跳转到 href 指向的另一个页面(非锚点情况)。

Redux

对 Redux 的理解

  • 集中管理管理数据状态,并进行可回溯,可预测更新的 js 应用工具,单纯的 redux 是一个状态机,没有 UI 呈现。
  • Redux 提供了一个叫 store 的统一仓储库,
    组件通过 dispatch 将 state 直接传入 store,不用通过其他的组件。
    并且组件通过 subscribe 从 store 获取到 state 的改变。
    使用了 Redux,所有的组件都可以从 store 中获取到所需的 state,他们也能从 store 获取到 state 的改变。
  • react-redux 作用就是将 redux 的状态机和 react 的 UI 呈现绑定在一起,当你 dispatch action 改变 state 的时候,更新页面。

Redux 的工作流程

  • view -→> action -> reducer -> store
  • 有中间件:view -> action -> middleware -> reducer -> store
  • const store= createStore(fn)生成数据;
  • action: {type: Symble('action01), payload:‘payload’ }定义行为;
  • dispatch 发起 action:store.dispatch(doSomething(‘action001’));
  • reducer:处理 action,返回新的 state;

redux 什么是纯函数 为什么 reducer 是纯函数

  • 因为比较两个 javascript 对象中所有的属性是否完全相同,唯一的办法就是深比较,然而,深比较在真实的应用中代码是非常大的,非常耗性能的,需要比较的次数特别多,所以一个有效的解决方案就是做一个规定,当无论发生任何变化时,开发者都要返回一个新的对象,没有变化时,开发者返回就的对象,这也就是 redux 为什么要把 reducer 设计成纯函数的原因。

Redux 和 Vuex 有什么区别,它们的共同思想

  1. Redux 和 Vuex 区别
  • Vuex 改进了 Redux 中的 Action 和 Reducer 函数,以 mutations 变化函数取代 Reducer,无需 switch,只需在对应的 mutation 函数里改变 state 值即可
  • Vuex 由于 Vue 自动重新渲染的特性,无需订阅重新渲染函数,只要生成新的 State 即可
  • Vuex 数据流的顺序是 ∶View 调用 store.commit 提交对应的请求到 Store 中对应的 mutation 函数->store 改变(vue 检测到数据变化自动渲染)

通俗点理解就是,vuex 弱化 dispatch,通过 commit 进行 store 状态的一次更变;取消了 action 概念,不必传入特定的 action 形式进行指定变更;弱化 reducer,基于 commit 参数直接对数据进行转变,使得框架更加简易; 2. 共同思想

  • 单—的数据源
  • 变化可以预测
    本质上 ∶ redux 与 vuex 都是对 mvvm 思想的服务,将数据从视图中抽离的一种方案。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值