react

124 阅读11分钟
  • react组件的生命周期

      挂载阶段、更新阶段、卸载阶段
    在`render()`方法中,根据组件的`props``state`返回一个React元素,用于描述组件的UI,真正渲染出页面DOM的工作由React自身负责。`render`是一个纯函数,在这个方法中不能执行任何有副作用的操作,不能去改变组件的状态。
       `componentDidMount()`在组件被挂载到DOM之后调用,而且该方法只会被调用一次。这个时候已经可以获取到DOM结构,因此依赖DOM节点的操作可以放到该方法中。此外,这个方法通常还会用于向服务器端请求数据,在这个方法中可以调用`this.setState()`,调用`this.setState()`会引起组件的重新渲染。。
    `componentDidUpdate`在组件更新之后被调用,可以作为操作更新后的DOM的地方组件被挂载到DOM后,`props``state`都可以引起组件的更新。
        -   `componentWillUnmount`在组件被卸载前调用,可以在这里执行一些清理工作,比如清除组件中使用的定时器,清除`componentDidMount`中手动创建的DOM元素等,以避免引起内存泄露。
    
  • 什么是jsx

     JSX是一种JavaScript的语法扩展,JSX会被babel编译为:React.createElement(),
     React.createElement()将返回一个叫作“ReactElement”的JS对象。可以在 `if` 语句和 `for` 循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX
    
  • 常见hook的使用

    usestate  `useState()` 方法里面唯一的参数就是初始 state
    hook规则,只在最顶层使用 Hook,不要在循环,条件或嵌套函数中调用 Hook,### 只在 React 函数中调用 Hook
    useeffect 你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数
    默认情况下,它在第一次渲染之后*和*每次更新之后都会执行。
    
    useMemo 在父组件给子组件传递参数时,如果父组件的对象属性发生变化,那么子组件也会重新渲染,useMemo可以在父组件传递的参数没有发生变化时,不会重新渲染子组件,传入两个参数,-   第一个参数是个函数,返回的对象指向同一个引用,不会创建新对象;-   第二个参数是个数组,只有数组中的变量改变时,第一个参数的函数才会返回一个新的对象。
    useCallback 父组件state变化,重新渲染,会重新创建方法函数,传给子组件的方法属性发生变化,导致子组件渲染
    useContext 处理层级较深的组件间传递,在组件外部createContext,使用Context.Provider提供一个context对象,在子组件中使用useContext可以获取到祖组件的值。
    
  • render方法触发的条件

    父组件传递给子组件值props
    父组件state发生变化
    组件state发生变化
    
  • react的合成事件系统

    通过 JSX 方式绑定的事件,比如 onClick={() => this.handle()},基于浏览器的事件机制实现的,通过冒泡事件冒泡到顶层元素,再统一分发处理
    
  • 什么是高阶组件hoc

    用于复用组件逻辑,高阶组件是函数,它接受一个组件作为参数,然后返回一个新的组件,一种设计模式,类似于装饰器模式
    
  • key的作用

    在render函数执行的时候,新旧两个虚拟DOM会进行对比,如果两个元素有不同的key,那么在前后两次渲染中就会被认为是不同的元素,这时候旧的那个元素会被销毁,新的元素会被创建。如果提供了唯一的标识key且是相同的key,且元素类型相同, 若元素属性有所变化,则React只更新组件对应的属性,这种情况下,性能开销会相对较小。
    
  • context的用法与使用场景

  • 错误边界(Error Boundaries)用法与使用场景

    页面由于某个 `React` 组件渲染错误(代码书写错误不规范或后端接口字段调整出错),导致整个应用被挂载出现白屏,且可能无法追踪造成影响极大,**任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载**`Error Boundaries` 是一种 React 组件,这种组件**可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,且会渲染出兜底 UI**

1.2.2. redux

  • 为什么要使用redux,解决了什么痛点

    redux解决的是react组件之间通信以及项目的状态变量的保存问题。如果不使用redux,随着项目的越来越大,组件之间通信越来越复杂,组件的状态越来越多,项目将越来越难以维护。使用redux之后,项目的状态都保存到store之中,各个组件可以直接从store之中获取到自己需要的状态,如果需要改变store中的状态,redux也提供了dispatch方法,组件可以dispatch一个action,根据action的type属性,reducer会对状态做出变化。
    
  • 阐述redux三大原则

    单一数据源,整个应用的 被储存在唯一的一个store中
    State 是只读的:唯一改变 state 的方法就是触发 [action],action 是一个用于描述已发生事件的普通对象。
    使用纯函数来执行修改。Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state
    
  • 阐述redux数据流过程

    严格的单向数据流,调用[`store.dispatch(action)`],Redux store 调用传入的 reducer 函数
    [Store] 会把两个参数传入 [reducer]: 当前的 state 树和 action。**根 reducer 应该把多个
    子 reducer 输出合并成一个单一的 state 树****Redux store 
    保存了根 reducer 返回的完整 state 树。**
    
  • 如果注册了两个一模一样的reducer,会产生什么问题

    state变量,是从方法的参数中传递过来的,意味着在第一个reducer执行完后的变化还没有对这个state产生影响,在第二个reducer执行的时候还是原来state的值。
    
  • 阐述redux的middleware,其目的是什么

    如果没有中间件的运用,redux 的工作流程是这样 action -> reducer,这是相当于同步操作,由dispatch 触发action后,直接去reducer执行相应的动作。有了中间件,redux 的工作流程就变成这样 action -> middlewares -> reducer,点击按钮就相当于dispatch 触发action,接下去获取服务器数据 middlewares 的执行,当 middlewares 成功获取到服务器就去触发reducer对应的动作,更新需要渲染视图的数据
    
  • 阐述combineReducers作用及其原理

    随着应用变得越来越复杂,可以考虑将 [reducer 函数] 拆分成多个单独的函数,拆分后的每个函数负责独立管理 [state]的一部分。 合并后的 reducer 可以调用各个子 reducer,并把它们返回的结果合并成一个 state 对象。
    

1.2.3. dva

  • 什么是dva,解决了什么痛点dva

    首先是一个基于 redux和 redux-saga的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router和 fetch,所以也可以理解为一个轻量级的应用框架。
    
  • 阐述Model对象的基本组成及其作用

    这个模块我理解的是主要用来处理数据,就是所谓的数据层,model主要包含五个部分
    namespace:命名空间
    state:数据的初始化,优先级低于 dva() 的 opts.initialState
    reducers:同步更新state,唯一可以更改state的地方,通过action触发
    effects:异步更新state,不直接修改state,通过action触发
    subscriptions:订阅数据源(数据源可以是当前的时间,服务器的 websocket连接, keyboard输入,geolocation变化,history路由变化等等),然后根据需要 dispatch相应的 action
    
  • @umijs/plugin-dva的启用条件是什么

    配置开启`immer`**约定式的 model 组织方式****文件名即 namespace**
    
  • dva-loading的实现原理

    可以自动处理 loading 状态,不用一遍遍地写 showLoading 和 hideLoading
    

1.2.4. redux-saga

  • redux-saga是什么,解决了什么痛点?

    主要是为了更优雅地 管理 Redux 应用程序中的 副作用,映射在 Javascript 程序中,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易。
    
  • 什么是saga

  • 什么是Effect

    Side Effects 主要指的就是:异步网络请求、本地读取 localStorage/Cookie 等外界操作
    
  • 执行dispatch(action)时,redux-saga经历了什么过程

    middleware 我们需要发起一些 action,然后让 middleware 执行真实的 dispatch
    

1.2.5. react-redux

  • 阐述react-redux的作用

    作用1将组件分为了容器组件和UI组件,UI组件通过props来获取状态和操作状态的方法
    作用2通过Provider组件来取代redux中的store.subscribe来监听组件的状态变化,用于渲染组件
    作用3在容器组件中通过核心API connect来连接UI组件和redux,connect是一个高阶函数,第一个参数接收的是两个回调函数,
    回调函数1:将接收一个state,然后返回一个对象对象中包含了UI组件想要的状态
    回调函数2:接收一个dispatch,返回一个对象,对象中包含了UI组件想要操作状态的方法同时还有一个简写方法,就是第二个参数直接传入一个对象,该对象包含操作状态的方法(核心:就是将state和dispatch映射到UI组件的props中)
    
  • 阐述Provider,connect,useSelector相关API的用法

    useSelector相关API的用法 从redux的store对象中提取数据
    connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
    Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。
    
  • 阐述store变化到组件更新的整个流程

    UI组件会先通过useDIspatch或者connect的mapDispatchToProps分发action,通过reducer纯函数去修改store的statestate发生变化后,通过UI组件的props会引起组件的更新。
    
  • 如何避免store变化时无关组件频繁渲染

    通过useMemo去监听数据的变化
    

1.2.6. react-router

  • 阐述hashHistory与browserRouter的区别

     BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。HashRouter使用的是URL的哈希值。
     BrowserRouter的路径中没有#1.  
     刷新后对路由state参数的影响BrowserRouter没有任何影响,因为state保存在history对象中。HashRouter刷新后会导致路由state参数的丢失!!!
    
  • 阐述Router、Route相关API的用法

    Router有BrowserRouter、HashRouter、MemoryHistory
    Route只是一个具有渲染方法的普通 React 组件,路由匹配成功则渲染该组件。
        path:路由的匹配规则(可以省略)
        exact:用于精确匹配路由(可以省略)
        component:需要渲染的组件
    顶层的 Router 组件负责分析监听 URL 的变化,在它之下的 Route 组件可以直接读取这些信息。Router 是“提供者”,Route是“消费者”
    
  • 如何渲染多层级路由

    嵌套路由children
    
  • 阐述路由变化到组件更新的整个过程

    当我们点击Link组件的时候,修改了浏览器地址栏中的url
    React路由监听地址栏url的变化
    React路由内部遍历所有的Route组件,拿着Route里面path规则与pathname进行匹配
    
  • 阐述history的底层机制

    用户访问网页的历史记录通常会被保存在一个类似于栈中,即history对象,点击返回就出栈,跳下一页就入栈。 它提供了方法操作页面的前进和后退:
    
    -   window.history.back() 返回到上一个页面
    -   window.history.forward() 进入到下一个页面
    -   window.history.go([delta]) 跳转到指定页面
    

1.2.7. umi

  • 阐述对umi框架的认识

    Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展,Umi 实现了完整的生命周期,并使其插件化,Umi 内部功能也全由插件完成
    
  • 项目中用到了哪些umi plugin,分别是什么作用

    plugin-antd
    plugin-dva
    plugin-layout
    
  • 从执行umi dev到页面启动,umi做了啥

    启动在浏览器中运行的开发服务器,并监视源文件变化,自动热加载。
    
  • 分析.umi目录到组成与作用

    .umi 临时目录是整个 Umi 项目的发动机,你的入口文件、路由等等都在这里,这些是由 umi 内部插件及三方插件生成的
    ```+ .umi+ core     # 内部插件生成
    + pluginA  # 外部插件生成
    + presetB  # 外部插件生成
    + umi.ts   # 入口文件
    

-   如何注册、使用一个umi plugin
Plugin.register
Plugin.applyPlugins