react

一、JSX简介

JSX,是一个 JavaScript 的语法扩展。JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。,但它具有 JavaScript 的全部功能。

将 HTML 直接嵌入了 JS 代码里面

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

JSX 是 JavaScript 语法的一种语法扩展,并拥有 JavaScript 的全部功能。JSX 生产 React “元素”,你可以将任何的 JavaScript 表达式封装在花括号里,然后将其嵌入到 JSX 中。在编译完成之后,JSX 表达式就变成了常规的 JavaScript 对象,这意味着你可以在 if 语句和 for 循环内部使用 JSX,将它赋值给变量,接受它作为参数,并从函数中返回 它。

二、为什么使用JSX

React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。

React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离

三、什么是React

React是一个简单的javascript UI库,用于构建高效、快速的用户界面。

React 的核心思想是:封装组件。

各个组件维护自己的状态和UI,当状态变更,自动重新渲染整个组件。

基于这种方式的一个直观感受就是我们不再需要不厌其烦地来回查找某个 DOM元素,然后操作 DOM 去更改 UI。

四、react生命周期函数

1、初始化阶段:

getDefaultProps:获取实例的默认属性

getInitialState:获取每个实例的初始化状态

componentWillMount:组件即将被装载、渲染到页面上

render:组件在这里生成虚拟的 DOM 节点

componentDidMount:组件真正在被装载之后

2、运行中状态:

render:组件重新描绘

3、销毁阶段:

componentWillUnmount:组件即将销毁

五、 为什么虚拟 dom 会提高性能?

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要 的 dom 操作,从而提高性能。

具体实现步骤如下:

1.用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树, 插到文档当中;

2.当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录 两棵树差异;

把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了

六、diff 算法

1.把树形结构按照层级分解,只比较同级元素。

2.给列表结构的每个单元添加唯一的 key 属性,方便比较。

3.React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)

4…合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个 事件循环结束, React 检查所有标记 dirty 的 component 重新绘制

5.选择性子树渲染

七、简述 flux 思想

Flux的最大特点:就是数据的"单向流动",数据总是"单项流动",任何相邻的部分都不会发生数据的"双向流动"。

1.用户访问view
2.view发出用户的Action
3.dispatcher收到Action,要求Store进行响应的更新
4.Store更新后,发出一个"change"事件
5.view收到"change"事件后,更新页面

Flux将一个应用分成四个部分;
1.view视图层
2.action(动作);视图层发出的消息(比如mouseClick)
3.Dispatcher(派发器):用来接收Actions,执行回调函数
4.Store(数据层):用来存放应用的状态,一旦发生改变,就提醒Views更新页面

八、什么是虚拟dom

当组件状态 state 有更改的时候,React 会自动调用组件的 render 方法重新渲染整个组件的 UI。

当然如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个VirtualDOM,组件 DOM 结构就是映射到这个 Virtual DOM 上,React 在这个 Virtual DOM上实现了一个 diff 算法,当要重新渲染组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个 Virtual DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多。

九、了解 shouldComponentUpdate 吗

React 虚拟 dom 技术要求不断的将 dom 和虚拟 dom 进行 diff 比较,如果 dom 树比价大, 这种比较操作会比较耗时,因此 React 提供了 shouldComponentUpdate 这种补丁函数,如 果对于一些变化,如果我们不希望某个组件刷新,或者刷新后跟原来其实一样,就可以 使用这个函数直接告诉 React,省去 diff 操作,进一步的提高了效率。

十、react工作原理

React 会创建一个虚拟 DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会 通过 “diffing” 算法来标记虚拟 DOM 中的改变,第二步是调节(reconciliation),会用 diff 的结果来更新 D

十一、 使用 React 有何优点?

1.只需查看 render 函数就会很容易知道一个组件是如何被渲染的

2.JSX 的引入,使得组件的代码更加可读,也更容易看懂组件的布局,或者组件之间是 如何互相引用的

3.支持服务端渲染,这可以改进 SEO 和性能

4.易于测试

5.React 只关注 View 层,所以可以和其它任何框架(如 Backbone.js, Angular.js)一起使

十二、展示组件(Presentational component)和容器组件(Container component)之间有 何不同

1.展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不 会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据 的状态。

容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供 数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器 组件经常是有状态的,因为它们是(其它组件的)数据源

十三、类组件(Class component)和函数式组件(Functional component)之间有何不 同

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

函数式组件,他一般用于静态没有交互事件内容的组件页面,接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

一般称为动态组件,一般会有交互或者数据修改的操作,实际开发还是用这个比较多我感觉

可以使用 ES6 的 class 来定义组件:

十四、(组件的)状态(state)和属性(props)之间有何不同

  1. State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的 推移而发生突变,但多数时候是作为用户事件行为的结果。

  2. Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组 件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件

    的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。

十五、何为高阶组件(higher order comp

高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑 和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的 组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写 了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。

十六、为什么建议传递给 setState 的参数是一个 callback 而不是一个对象

因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。

十七、react路由

目前我们所接触到的react例子都是单页面的,只有一个页面组件,在实际项目中通常都会有多个页面存在,可以通过链接来进行切换,达到多页面的效果。要实现这个功能,我们需要借助于React的路由模块 react-router-dom 来实现,它可以让我们监听浏览器地址的变化,并且解析这个URL对象,然后router根据URL的路径匹配到路由对应页面组件,最后正确地渲染对应地组件,这个就是路由工作的基本原理。

十八、less

Less是一种CSS的预处理语言,它在CSS的基础上增加了一些编程语言的特性,可以提升我们编写CSS的效率,减少很多重复性的代码,最终编译成纯净的CSS代码执行。

变量(Variables)
@width: 10px;
@height: @width + 10px;
@color: #f00;

.header {
  width: @witth;
  height: @height;
  height: @color;
}
混合(Mixins)

Mixin 是一种将一组属性从一个规则集混入到另一个规则集的方法。假设我们定义了一个类如下

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

如果我们想要在其他类中混入这些属性,只需要像函数一样调用他们即可:

.menu a {
  color: #111;
  .bordered();
}

.post a {
  color: red;
  .bordered();
}
嵌套(Nesting)

Less提供了嵌套代替层叠或者与层叠结合使用的能力,假如我们有下面的CSS代码

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

如果使用Less,我们可以这样来写

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

十九、Ant Design

Ant Design 是阿里推出的一套设计体系,antd 是基于这套设计体系的 React UI 组件库,主要用于开发企业级的中后台产品,它的组件质量非常高,而且使用TypeScript开发,提供完整的类型定义文件,是React社区最为知名的组件库

MobX

目前我们所接触到的React中的状态都只在组件内部或者父子组件之间传递,但是有些特殊的状态我们需要在很多不同的组件中都能访问它,而且当这些状态发生变化的时候可以引起界面的刷新,比如我们可以把当前登录的用户信息放到全局状态中,其他组件可以直接引用。

二十、NodeJs

Node.js 是一个基于 Chrome V8 引擎的 JS 运行环境,它采用了单线程,事件驱动、非阻塞式的 I/O 模型,尤其适合构建 I/O 密集型的高性能服务端,如今整个前端生态的工具链都构建在 Node.js 的基础之上

简单的说 Node.js 就是运行在服务端的 JavaScript

二十一、MVC、MVP、MVVM模式的概念与区别

**Model(模型)**是应用程序中用于处理应用程序数据逻辑的部分。
 通常模型对象负责在数据库中存取数据。

**View(视图)**是应用程序中处理数据显示的部分。
 通常视图是依据模型数据创建的。

**Controller(控制器)**是应用程序中处理用户交互的部分。
 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据

模型

模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。

视图

就像在MVC和MVP模式中一样,视图是用户在屏幕上看到的结构、布局和外观(UI)。

视图模型

视图模型是暴露公共属性和命令的视图的抽象。MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信。

绑定器

声明性数据和命令绑定隐含在MVVM模式中。在Microsoft解决方案堆中,绑定器是一种名为XAML的标记语言。绑定器使开发人员免于被迫编写样板式逻辑来同步视图模型和视图。在微软的堆之外实现时,声明性数据绑定技术的出现是实现该模式的一个关键因素

什么是MVVM?

视图模型双向绑定,是Model-View-ViewModel的缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModelViewModel层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。以前是操作DOM结构更新视图,现在是数据驱动视图

MVVM的优点:

1.低耦合。视图(View)可以独立于Model变化和修改,一个Model可以绑定到不同的View上,当View变化的时候Model可以不变化,当Model变化的时候View也可以不变;
2.可重用性。你可以把一些视图逻辑放在一个Model里面,让很多View重用这段视图逻辑。
3.独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
4.可测试

二十二、hooks用过吗?聊聊react中class组件和函数组件的区别

类组件是使用ES6 的 class 来定义的组件。 函数组件是接收一个单一的 props 对象并返回一个React元素。

关于React的两套API(类(class)API 和基于函数的钩子(hooks) API)。官方推荐使用钩子(函数),而不是类。因为钩子更简洁,代码量少,用起来比较"轻",而类比较"重"。而且,钩子是函数,更符合 React 函数式的本质。

函数一般来说,只应该做一件事,就是返回一个值。 如果你有多个操作,每个操作应该写成一个单独的函数。而且,数据的状态应该与操作方法分离。根据函数这种理念,React 的函数组件只应该做一件事情:返回组件的 HTML 代码,而没有其他的功能。函数的返回结果只依赖于它的参数。不改变函数体外部数据、函数执行过程里面没有副作用。

类(class)是数据和逻辑的封装。 也就是说,组件的状态和操作方法是封装在一起的。如果选择了类的写法,就应该把相关的数据和操作,都写在同一个 class 里面。

类组件的缺点 :

大型组件很难拆分和重构,也很难测试。
业务逻辑分散在组件的各个方法之中,导致重复逻辑或关联逻辑。
组件类引入了复杂的编程模式,比如 render props 和高阶组件。
难以理解的 class,理解 JavaScript 中 this 的工作方式。

区别

函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。

1.状态的有无
hooks出现之前,函数组件没有实例没有生命周期没有state没有this,所以我们称函数组件为无状态组件。 hooks出现之前,react中的函数组件通常只考虑负责UI的渲染,没有自身的状态没有业务逻辑代码,是一个纯函数。它的输出只由参数props决定,不受其他任何因素影响。

2.调用方式的不同
函数组件重新渲染,将重新调用组件方法返回新的react元素。类组件重新渲染将new一个新的组件实例,然后调用render类方法返回react元素,这也说明为什么类组件中this是可变的。

3.因为调用方式不同,在函数组件使用中会出现问题
在操作中改变状态值,类组件可以获取最新的状态值,而函数组件则会按照顺序返回状态值

React Hooks(钩子的作用)

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

React Hooks的几个常用钩子:

  1. useState() //状态钩子
  2. useContext() //共享状态钩子
  3. useReducer() //action 钩子
  4. useEffect() //副作用钩子

还有几个不常见的大概的说下,后续会专门写篇文章描述下

  • 1.useCallback 记忆函数 一般把函数式组件理解为class组件render函数的语法糖,所以每次重新渲染的时候,函数式组件内部所有的代码都会重新执行一遍。而有了 useCallback 就不一样了,你可以通过 useCallback 获得一个记忆后的函数。

    function App() {
      const memoizedHandleClick = useCallback(() => {
        console.log('Click happened')
      }, []); // 空数组代表无论什么情况下该函数都不会发生改变
      return <SomeComponent onClick={memoizedHandleClick}>Click Me</SomeComponent>;
    }
    复制代码
    

    第二个参数传入一个数组,数组中的每一项一旦值或者引用发生改变,useCallback 就会重新返回一个新的记忆函数提供给后面进行渲染。

  • 2.useMemo 记忆组件 useCallback 的功能完全可以由 useMemo 所取代,如果你想通过使用 useMemo 返回一个记忆函数也是完全可以的。 唯一的区别是:useCallback 不会执行第一个参数函数,而是将它返回给你,而 useMemo 会执行第一个函数并且将函数执行结果返回给你
    所以 useCallback 常用记忆事件函数,生成记忆后的事件函数并传递给子组件使用。而 useMemo 更适合经过函数计算得到一个确定的值,比如记忆组件。

  • 3.useRef 保存引用值

    useRef 跟 createRef 类似,都可以用来生成对 DOM 对象的引用。useRef 返回的值传递给组件或者 DOM 的 ref 属性,就可以通过 ref.current 值访问组件或真实的 DOM 节点,重点是组件也是可以访问到的,从而可以对 DOM 进行一些操作,比如监听事件等等。

  • 4.useImperativeHandle 穿透 Ref

    通过 useImperativeHandle 用于让父组件获取子组件内的索引

  • 5.useLayoutEffect 同步执行副作用

    大部分情况下,使用 useEffect 就可以帮我们处理组件的副作用,但是如果想要同步调用一些副作用,比如对 DOM 的操作,就需要使用 useLayoutEffect,useLayoutEffect 中的副作用会在 DOM 更新之后同步执行。

    useEffect和useLayoutEffect有什么区别:简单来说就是调用时机不同,useLayoutEffect和原来componentDidMount&componentDidUpdate一致,在react完成DOM更新后马上同步调用的代码,会阻塞页面渲染。而useEffect是会在整个页面渲染完才会调用的代码。官方建议优先使用useEffect

二十三、React 组件通信方式

react组件间通信常见的几种情况:

    1. 父组件向子组件通信
    1. 子组件向父组件通信
    1. 跨级组件通信
    1. 非嵌套关系的组件通信
1)父组件向子组件通信

父组件通过 props 向子组件传递需要的信息。父传子是在父组件中直接绑定一个正常的属性,这个属性就是指具体的值,在子组件中,用props就可以获取到这个值

// 子组件: Child
const Child = props =>{
  return <p>{props.name}</p>
}

// 父组件 Parent
const Parent = ()=>{
    return <Child name="京程一灯"></Child>
}
复制代码
2)子组件向父组件通信

props+回调的方式,使用公共组件进行状态提升。子传父是先在父组件上绑定属性设置为一个函数,当子组件需要给父组件传值的时候,则通过props调用该函数将参数传入到该函数当中,此时就可以在父组件中的函数中接收到该参数了,这个参数则为子组件传过来的值

// 子组件: Child
const Child = props =>{
  const cb = msg =>{
      return ()=>{
          props.callback(msg)
      }
  }
  return (
      <button onClick={cb("京程一灯欢迎你!")}>京程一灯欢迎你</button>
  )
}

// 父组件 Parent
class Parent extends Component {
    callback(msg){
        console.log(msg)
    }
    render(){
        return <Child callback={this.callback.bind(this)}></Child>    
    }
}
复制代码
3)跨级组件通信

即父组件向子组件的子组件通信,向更深层子组件通信。

  • 使用props,利用中间组件层层传递,但是如果父组件结构较深,那么中间每一层组件都要去传递props,增加了复杂度,并且这些props并不是中间组件自己需要的。
  • 使用context,context相当于一个大容器,我们可以把要通信的内容放在这个容器中,这样不管嵌套多深,都可以随意取用,对于跨越多层的全局数据可以使用context实现。
// context方式实现跨级组件通信 
// Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据

const BatteryContext = createContext();

//  子组件的子组件 
class GrandChild extends Component {
    render(){
        return (
            <BatteryContext.Consumer>
                {
                    color => <h1 style={{"color":color}}>我是红色的:{color}</h1>
                }
            </BatteryContext.Consumer>
        ) 
    }
}

//  子组件
const Child = () =>{
    return (
        <GrandChild/>
    )
}
// 父组件
class Parent extends Component {
      state = {
          color:"red"
      }
      render(){
          const {color} = this.state
          return (
          <BatteryContext.Provider value={color}>
              <Child></Child>
          </BatteryContext.Provider> 
          )
      }
}
复制代码
4)非嵌套关系的组件通信

即没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。

    1. 可以使用自定义事件通信(发布订阅模式),使用pubsub-js
    1. 可以通过redux等进行全局状态管理
    1. 如果是兄弟组件通信,可以找到这两个兄弟节点共同的父节点, 结合父子间通信方式进行通信。
    1. 也可以new一个 Vue 的 EventBus,进行事件监听,一边执行监听,一边执行新增 VUE的eventBus 就是发布订阅模式,是可以在React中使用的;

二十四、setState 既存在异步情况也存在同步情况

1.异步情况 在React事件当中是异步操作

2.同步情况 如果是在setTimeout事件或者自定义的dom事件中,都是同步的

//setTimeout事件
import React,{ Component } from "react";
class Count extends Component{
    constructor(props){
        super(props);
        this.state = {
            count:0
        }
    }

    render(){
        return (
            <>
                <p>count:{this.state.count}</p>
                <button onClick={this.btnAction}>增加</button>
            </>
        )
    }
    
    btnAction = ()=>{
        //不能直接修改state,需要通过setState进行修改
        //同步
        setTimeout(()=>{
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count);
        })
    }
}

export default Count;
复制代码
//自定义dom事件
import React,{ Component } from "react";
class Count extends Component{
    constructor(props){
        super(props);
        this.state = {
            count:0
        }
    }

    render(){
        return (
            <>
                <p>count:{this.state.count}</p>
                <button id="btn">绑定点击事件</button>
            </>
        )
    }
    
    componentDidMount(){
        //自定义dom事件,也是同步修改
        document.querySelector('#btn').addEventListener('click',()=>{
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count);
        });
    }
}

export default Count;
复制代码

二十五、生命周期

image.png

安装
当组件的实例被创建并插入到 DOM 中时,这些方法按以下顺序调用:

constructor()
static getDerivedStateFromProps()
render()
componentDidMount()

更新中
更新可能由道具或状态的更改引起。当重新渲染组件时,这些方法按以下顺序调用:

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

卸载
当组件从 DOM 中移除时调用此方法:

componentWillUnmount()
复制代码

二十六、说一下 react-fiber

1)背景

react-fiber 产生的根本原因,是大量的同步计算任务阻塞了浏览器的 UI 渲染。默认情况下,JS 运算、页面布局和页面绘制都是运行在浏览器的主线程当中,他们之间是互斥的关系。如果 JS 运算持续占用主线程,页面就没法得到及时的更新。当我们调用setState更新页面的时候,React 会遍历应用的所有节点,计算出差异,然后再更新 UI。如果页面元素很多,整个过程占用的时机就可能超过 16 毫秒,就容易出现掉帧的现象。

2)实现原理
  • react内部运转分三层:
    • Virtual DOM 层,描述页面长什么样。
    • Reconciler 层,负责调用组件生命周期方法,进行 Diff 运算等。
    • Renderer 层,根据不同的平台,渲染出相应的页面,比较常见的是 ReactDOM 和 ReactNative。

Fiber 其实指的是一种数据结构,它可以用一个纯 JS 对象来表示

const fiber = {
    stateNode,    // 节点实例
    child,        // 子节点
    sibling,      // 兄弟节点
    return,       // 父节点
}
复制代码
  • 为了实现不卡顿,就需要有一个调度器 (Scheduler) 来进行任务分配。优先级高的任务(如键盘输入)可以打断优先级低的任务(如Diff)的执行,从而更快的生效。任务的优先级有六种:
    • synchronous,与之前的Stack Reconciler操作一样,同步执行
    • task,在next tick之前执行
    • animation,下一帧之前执行
    • high,在不久的将来立即执行
    • low,稍微延迟执行也没关系
    • offscreen,下一次render时或scroll时才执行
  • Fiber Reconciler(react )执行过程分为2个阶段:
    • 阶段一,生成 Fiber 树,得出需要更新的节点信息。这一步是一个渐进的过程,可以被打断。阶段一可被打断的特性,让优先级更高的任务先执行,从框架层面大大降低了页面掉帧的概率。
    • 阶段二,将需要更新的节点一次过批量更新,这个过程不能被打断。
  • Fiber树:React 在 render 第一次渲染时,会通过 React.createElement 创建一颗 Element 树,可以称之为 Virtual DOM Tree,由于要记录上下文信息,加入了 Fiber,每一个 Element 会对应一个 Fiber Node,将 Fiber Node 链接起来的结构成为 Fiber Tree。Fiber Tree 一个重要的特点是链表结构,将递归遍历编程循环遍历,然后配合 requestIdleCallback API, 实现任务拆分、中断与恢复。

从Stack Reconciler到Fiber Reconciler,源码层面其实就是干了一件递归改循环的事情

传送门 ☞# 深入了解 Fiber

二十七、Portals

Portals 提供了一种一流的方式来将子组件渲染到存在于父组件的 DOM 层次结构之外的 DOM 节点中。结构不受外界的控制的情况下就可以使用portals进行创建

二十八、何时要使用异步组件?如和使用异步组件

  • 加载大组件的时候
  • 路由异步加载的时候

react 中要配合 Suspense 使用

// 异步懒加载
const Box = lazy(()=>import('./components/Box'));
// 使用组件的时候要用suspense进行包裹
<Suspense fallback={<div>loading...</div>}>
    {show && <Box/>}
</Suspense>
复制代码

二十九、React 事件绑定原理

React并不是将click事件绑在该div的真实DOM上,而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。
另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault

react事件绑定原理

节点中。结构不受外界的控制的情况下就可以使用portals进行创建

二十八、何时要使用异步组件?如和使用异步组件

  • 加载大组件的时候
  • 路由异步加载的时候

react 中要配合 Suspense 使用

// 异步懒加载
const Box = lazy(()=>import('./components/Box'));
// 使用组件的时候要用suspense进行包裹
<Suspense fallback={<div>loading...</div>}>
    {show && <Box/>}
</Suspense>
复制代码

二十九、React 事件绑定原理

React并不是将click事件绑在该div的真实DOM上,而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。
另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault

[外链图片转存中…(img-KlRa383H-1634800363170)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值