react 面试总结

1.什么是react

 React](https://reactjs.org) 是一个专用于构建 **用户界面** 的JavaScript 库。

 React核心
 核心概念
 组件
 你对组件的理解?
 可组合,可复用,可维护,可测试

2. React的特点是什么?

● 声明式设计:react采用范式声明,开发者只需要声明显示内容,react就会自动完成
● 高效: react通过对dom的模拟(也就是虚拟dom),最大限度的减少与dom的交互
● 灵活: react可以和已知的库或者框架很好配合
● 组件化: 通过react构建组件,让代码更容易复用,能够很好应用在大型项目开发中,把页面功能拆分成小模块 每个小模块就是组件
● 单向数据流: react是单向数据流,数据通过props从父节点传递到子节点,如果父级的某个props改变了,react会重新渲染所有的子节点

 3. 什么是JSX?

JSX是一种JavaScript的语法扩展,它允许我们在JavaScript中编写类似HTML的代码。它是React的核心之一,用于描述UI组件的结构和样式。

 4. React中的组件有哪些类型?

React中的组件可以分为两种类型:

函数组件:使用函数来定义组件。
类组件:使用ES6类来定义组件。

 4.1 列出React的一些主要优点

  1. 通过虚拟 DOM 提高应用程序的性能。
  2. JSX 使代码易于阅读和编写。
  3. 它在客户端和服务器端都能进行渲染(SSR)。
  4. 易于与框架(Angular, Backbone)集成,因为它只是一个视图库。
  5. 使用 Jest 等工具容易编写单元和集成测试。

 4.2 React局限性

  1. React 只是一个视图库,不是一个完整的框架。
  2. 对于刚接触网络开发的初学者来说,有一个学习曲线。
  3. 将 React 整合到传统的 MVC 框架中需要一些额外的配置。
  4. 代码的复杂性随着内联模板和 JSX 的增加而增加。
  5. 太多的小组件导致了过度工程化或模板化。

 4.2 如何模块化 React 中的代码?

可以使用export、import属性来模块化代码。它们有助于在不同的文件中单独编写组件。

重点 react vs vue?/ vue 与react的区别?(大华、阿里)

一、相同点:
● 都支持服务器渲染
● 都有虚拟dom,组件化开发,通过props参数进行父子组件数据的传递,都实现webcomponent规范
● 都是数据驱动视图
● 都有状态管理,react有redux,vue有vuex
● 都有支持native的方案 react有react native vue有weex
二、不同点:
● react严格上只针对mvc的view层,vue是mvvm模式
● 模板渲染方式不同
○ 模板的语法不同,React是通过jsx渲染,vue是通过一种拓展的html语法进行渲染。
○ 模板的原理不同:React是在组件JS代码中,通过原生JS实现模板中的常见语法,如插值、条件、循环等,都是通过JS语法实现的,更加纯粹更加原生。Vue是在和组件JS代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要v-if来实现这一点。
● 虚拟dom不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个dom组件树,而react不同,当应用的状态被改变时,全部组件都会重新渲染,所以react中用shouldcomponentupdate这个生命周期的钩子函数来控制
● 组件写法不一样 ,react是jsx和inline style ,就是把html和css全写进js中,vue则是html,css ,js在同一个文件
● 数据绑定不一样,vue实现了数据双向绑定,react数据流动是单向的
● 在react中,state对象需要用setstate方法更新状态,在vue中,state对象不是必须的,数据由data属性在vue对象中管理

vue, react 适用场景? / vue, react 技术选型?

● 应用需要尽可能小和快就用vue, vue渲染速度比react 快
● 大型项目建议用react,因为vue模板的使用不容易发现错误、也不易拆分和测试
● 如果要适用于web 和原生app的项目,就使用react native

vue、react的区别和联系?

vue, react的模板渲染、两者的虚拟dom、diff差异(vue2、vue3、react16)、两者的批量更新,还有路由差异、常用的优化手段、怎么进行数据通信、讲点新鲜的内容:vue3有什么特性、最后总结,谈谈两者的如今的生态。。。

5. 什么是props?

props是React中传递给组件的属性。它们是只读的,不能在组件内部更改。可以将props视为组件的配置。是一种传值的方式

6. 什么是state?

state是React中用于存储组件内部状态的对象。它们是可变的,可以在组件内部更改。当state发生变化时,组件将重新渲染。  状态管理工具

7. 什么是生命周期方法?

生命周期方法是React中的一组特殊方法,它们在组件的生命周期中被调用。这些方法使我们能够在组件的不同阶段执行特定的操作,例如初始化组件、更新组件、卸载组件等。

8. React中有哪些生命周期方法?

React中有三个生命周期阶段:

挂载阶段:组件被创建并添加到DOM中。
更新阶段:组件的props或state发生变化时,组件被重新渲染。
卸载阶段:组件被从DOM中移除。
在这些阶段中,React提供了以下生命周期方法:

constructor()
static getDerivedStateFromProps()
render()
componentDidMount()
shouldComponentUpdate()
getSnapshotBeforeUpdate()
componentDidUpdate()
componentWillUnmount()

9. 什么是constructor()方法?

constructor()方法是React组件的构造函数。它在组件被创建时被调用,并且可以用于初始化组件的状态和绑定方法。

10. 什么是render()方法?

render()方法是React组件的核心方法之一。它返回组件的虚拟DOM结构,并负责处理组件的渲染。

11. 什么是componentDidMount()方法?

componentDidMount()方法是React组件的生命周期方法之一。它在组件被添加到DOM中后被调用,并且可以用于执行一些初始化操作,例如获取数据或添加事件监听器。

12. 什么是shouldComponentUpdate()方法?

shouldComponentUpdate()方法是React组件的生命周期方法之一。它在组件的props或state发生变化时被调用,并且可以用于决定是否需要重新渲染组件。

13. 什么是componentDidUpdate()方法?

componentDidUpdate()方法是React组件的生命周期方法之一。它在组件的props或state发生变化后被调用,并且可以用于执行一些更新操作,例如更新DOM或重新获取数据。

14. 什么是componentWillUnmount()方法?

componentWillUnmount()方法是React组件的生命周期方法之一。它在组件被卸载之前被调用,并且可以用于执行一些清理操作,例如取消事件监听器或清除定时器。

15. 什么是setState()方法?

setState()方法是React组件的方法之一。它用于更新组件的状态,并且会触发组件的重新渲染。

16. 什么是React Router? 

React Router是一个用于构建单页应用程序的React库。它允许我们在应用程序中定义路由,并且可以根据URL的变化来渲染不同的组件。

17. React Router中有哪些组件?


React Router中有以下组件:

BrowserRouter:用于在应用程序中启用HTML5历史路由。
HashRouter:用于在应用程序中启用哈希路由。
Route:用于定义应用程序中的路由规则。
Switch:用于在多个路由规则中选择一个。
Link:用于在应用程序中导航到其他页面。

18. 什么是Redux?

Redux是一个用于管理应用程序状态的JavaScript库。它是一个单向数据流的架构,可以让我们更好地组织和管理应用程序的状态。 

19. Redux中有哪些核心概念?


Redux中有以下核心概念:

Store:用于管理应用程序的状态。
Action:用于描述发生的事件。
Reducer:用于处理Action并更新状态。
Dispatch:用于将Action发送到Reducer。

20. 什么是React Redux?

React Redux是一个用于在React应用程序中使用Redux的库。它提供了一些帮助程序,使我们能够更轻松地在React组件中使用Redux。

21. 如何在React中使用Redux?

在React中使用Redux需要执行以下步骤:

安装Redux和React Redux。
创建一个Redux store。
创建一个Reducer来处理Action并更新状态。
在React组件中使用connect()函数将组件连接到Redux store。

22. 什么是React Hooks?

React Hooks是React 16.8中引入的一组函数,它们使我们能够在函数组件中使用状态和其他React功能,而无需使用类组件。

23. React Hooks有哪些?

React Hooks有以下函数:

useState()
useEffect()
useContext()
useReducer()
useCallback()
useMemo()
useRef()
useImperativeHandle()
useLayoutEffect()
useDebugValue()

24. 什么是useState()? 

useState()是React Hooks中最常用的函数之一。它允许我们在函数组件中使用状态,并且可以在组件的生命周期中保持状态。

25. 什么是useEffect()?

useEffect()是React Hooks中的一个函数,它允许我们在函数组件中执行副作用操作,例如获取数据或添加事件监听器。它类似于componentDidMount()和componentDidUpdate()生命周期方法的组合。

26. 什么是useContext()?

useContext()是React Hooks中的一个函数,它允许我们在函数组件中使用React上下文。它可以让我们轻松地在组件之间共享数据。

27. 什么是useReducer()?

useReducer()是React Hooks中的一个函数,它允许我们在函数组件中使用Redux-style的reducer来管理状态。它可以让我们更好地组织和管理组件的状态。

28. 什么是useCallback()?

useCallback()是React Hooks中的一个函数,它允许我们在函数组件中缓存回调函数,以避免在每次渲染时重新创建它们。这可以提高组件的性能。

29. 什么是useMemo()?

useMemo()是React Hooks中的一个函数,它允许我们在函数组件中缓存计算结果,以避免在每次渲染时重新计算它们。这可以提高组件的性能。

30. 什么是useRef()?

useRef()是React Hooks中的一个函数,它允许我们在函数组件中创建一个可变的引用。它可以用于保存组件的状态,或者引用DOM元素。

什么是受控组件和非受控组件?

我们稍微了解下什么是受控组件和非受控组件:

受控组件:只能通过 React 修改数据或状态的组件,就是受控组件;
非受控组件:与受控组件相反,如 input, textarea, select, checkbox 等组件,本身控件自己就能控制数据和状态的变更,而且 React 是不知道这些变更的;
那么如何将非受控组件改为受控组件呢?那就是把上面的这些纯 html 组件数据或状态的变更,交给 React 来操作:

const App = () => {
  const [value, setValue] = useState('');
  const [checked, setChecked] = useState(false);
 
  return (
    <>
      <input value={value} onInput={event => setValue(event.target.value)} />
      <input type="checkbox" checked={checked} onChange={event => setChecked(event.target.checked)} />
    </>
  );
};
上面代码中,输入框和 checkbox 的变化,均是经过了 React 来操作的,在数据变更时,React 是能够知道的。

React 中为什么要使用 Hook?

在组件之间复用状态逻辑很难:在类组件中,可能需要 render props 和 高阶组件等方式,但会形成“嵌套地域”;而使用 Hook,则可以从组件中提取状态逻辑,是的这些逻辑可以单独测试并复用;
复杂组件变得难以理解:在类组件中,每个生命周期常常包含一些不相关的逻辑。如不同的执行逻辑,都要放在componentDidMount中执行和获取数据,而之后需在 componentWillUnmount 中清除;但在函数组件中,不同的逻辑可以放在不同的 Hook 中执行,互不干扰;
难以理解的 class:类组件中,充斥着各种对 this 的使用,如 this.onClick.bind(this),this.state,this.setState() 等,同时,class 不能很好的压缩,并且会使热重载出现不稳定的情况;Hook 使你在非 class 的情况下可以使用更多的 React 特性;
 

useCallback 和 useMemo 的使用场景

useCallback 和 useMemo 可以用来缓存函数和变量,提高性能,减少资源浪费。但并不是所有的函数和变量都需要用这两者来实现,他也有对应的使用场景。

我们知道 useCallback 可以缓存函数体,在依赖项没有变化时,前后两次渲染时,使用的函数体是一样的。它的使用场景是:

函数作为其他 hook 的依赖项时(如在 useEffect()中);
函数作为 React.memo()(或 shouldComponentUpdate )中的组件的 props;
主要是为了避免重新生成的函数,会导致其他 hook 或组件的不必要刷新。

useMemo 用来缓存函数执行的结果。如每次渲染时都要执行一段很复杂的运算,或者一个变量需要依赖另一个变量的运算结果,就都可以使用 useMemo()。

React 的 diff 过程

React 只对比当前层级的节点,不跨层级进行比较;
根据不同的节点类型,如函数组件节点、类组件节点、普通 fiber 节点、数组节点等,进入不同的处理函数;
前后两个 fiber 节点进行对比,若 type 不一样,直接舍弃掉旧的 fiber 节点,创建新的 fiber 节点;若 key 不一样,则需要根据情况判断,若是单个元素,则直接舍弃掉,创建新的 fiber 节点;若是数字型的元素,则查找是否移动了位置,若没找到,则创建新的节点;若 key 和 type 都一样,则接着往下递归;
若是单个 fiber 节点,则直接返回;若是并列多个元素的 fiber 节点,这里会形成单向链表,然后返回头指针(该链表最前面的那个 fiber 节点);
通过上面的 diff 对比过程,我们也可以看到,当组件产生比较大的变更时,React 需要做更多的动作,来构建出新的 fiber 树,因此我们在开发过程中,若从性能优化的角度考虑,尤其要注意的是:

节点不要产生大量的越级操作:因为 React 是只进行同层节点的对比,若同一个位置的子节点产生了比较大的变动,则只会舍弃掉之前的 fiber 节点,从而执行创建新 fiber 节点的操作;React 并不会把之前的 fiber 节点移动到另一个位置;相应的,之前的 jsx 节点移动到另一个位置后,在进行前后对比后,同样会执行更多的创建操作;
不修改节点的 key 和 type 类型,如使用随机数做为列表的 key,或从 div 标签改成 p 标签等操作,在 diff 对比过程中,都会直接舍弃掉之前的 fiber 节点及所有的子节点(即使子节点没有变动),然后重新创建出新的 fiber 节点;

31. 什么是useImperativeHandle()?
useImperativeHandle()是React Hooks中的一个函数,它允许我们在函数组件中自定义暴露给父组件的实例值。这可以用于创建可重用的组件。

32. 什么是useLayoutEffect()?
useLayoutEffect()是React Hooks中的一个函数,它类似于useEffect(),但是它在DOM更新之前同步触发。这可以用于处理需要同步更新DOM的情况。

33. 什么是useDebugValue()?
useDebugValue()是React Hooks中的一个函数,它允许我们在React开发工具中调试自定义Hooks的值。

34. 什么是React Native?
React Native是一个用于构建原生移动应用程序的React库。它允许我们使用JavaScript和React构建跨平台的应用程序,并且可以在iOS和Android上运行。

35. React Native中有哪些核心组件?
React Native中有以下核心组件:

View:类似于HTML中的div元素,用于包含其他组件。
Text:用于显示文本。
Image:用于显示图像。
TextInput:用于获取用户输入的文本。
ScrollView:用于滚动页面。
FlatList:用于显示列表。
TouchableOpacity:用于创建可点击的元素。
36. 什么是React Native CLI?
React Native CLI是React Native的命令行工具,用于创建和管理React Native应用程序。它允许我们在本地开发环境中构建和运行React Native应用程序。

37. 什么是Expo?
Expo是一个用于构建React Native应用程序的开发工具和服务平台。它提供了一些有用的功能,例如快速原型设计、自动构建和发布、设备测试等。

38. 什么是React Native Navigation?
React Native Navigation是一个用于在React Native应用程序中实现导航的库。它提供了一组易于使用的API,用于管理应用程序的导航栈和屏幕之间的转换。它支持多种导航类型,例如堆栈导航、标签导航和抽屉导航,并且可以与Redux等状态管理库集成使用。React Native Navigation还具有高性能、流畅的动画效果和自定义主题的能力,使得开发人员可以轻松地创建美观、易于使用的导航界面。

React声明组件有哪几种方法,有什么不同?/ React中有哪几种构建组件的方式?

一、React 声明组件的三种方式:
● 无状态函数式组件
○ 它是为了创建纯展示组件,这种组件只负责根据传入的props来展示,不涉及到state状态的操作
○ 组件不会被实例化,整体渲染性能得到提升,不能访问this对象,不能访问生命周期的方法
● ES5 原生方式 React.createClass定义的组件 // RFC
○ React.createClass会自绑定函数方法,导致不必要的性能开销,增加代码过时的可能性。
● ES6继承形式 extends React.Component定义的组件 // RCC
○ 目前极为推荐的创建有状态组件的方式,最终会取代React.createClass形式;相对于 React.createClass可以更好实现代码复用。
二、区别
1、无状态组件相对于于后者的区别:
(1)与无状态组件相比,React.createClass和React.Component都是创建有状态的组件,这些组件是要被实例化的,并且可以访问组件的生命周期方法。
2、React.createClass与React.Component区别:
(1)函数this自绑定
● React.createClass创建的组件,其每一个成员函数的this都有React自动绑定,函数中的this会被正确设置。
● React.Component创建的组件,其成员函数不会自动绑定this,需要开发者手动绑定,否则this不能获取当前组件实例对象。
(2)组件属性类型propTypes及其默认props属性defaultProps配置不同
● React.createClass在创建组件时,有关组件props的属性类型及组件默认的属性会作为组件实例的属性来配置,其中defaultProps是使用getDefaultProps的方法来获取默认组件属性的
● React.Component在创建组件时配置这两个对应信息时,他们是作为组件类的属性,不是组件实例的属性,也就是所谓的类的静态属性来配置的。
(3)组件初始状态state的配置不同
● React.createClass创建的组件,其状态state是通过getInitialState方法来配置组件相关的状态;
● React.Component创建的组件,其状态state是在constructor中像初始化组件属性一样声明的。

React 中构建组件的方式?
● 自定义组件:函数组件或者无状态组件 ,组件首字母大写
● 类组件:一个类组件必须实现一个render方法,这个方法必须返回一个jsx元素,要用一个外层的元素把所有内容包裹起来

你怎样理解“在React中,一切都是组件”这句话?

Component, Element, Instance 之间有什么区别和联系?
● 元素:一个元素element是一个普通对象(plain object),描述了对于一个DOM节点或者其他组件component,你想让它在屏幕上呈现成什么样子。元素element可以在它的属性props中包含其他元素(译注:用于形成元素树)。创建一个React元素element成本很低。元素element创建之后是不可变的。
● 组件:一个组件component可以通过多种方式声明。可以是带有一个render()方法的类,简单点也可以定义为一个函数。这两种情况下,它都把属性props作为输入,把返回的一棵元素树作为输出。
● 实例:一个实例instance是你在所写的组件类component class中使用关键字this所指向的东西(译注:组件实例)。它用来存储本地状态和响应生命周期事件很有用。
函数式组件(Functional component)根本没有实例instance。类组件(Class component)有实例instance,但是永远也不需要直接创建一个组件的实例,因为React帮我们做了这些。

如何有条件地向React组件添加属性?
对于某些属性,React非常聪明,如果传递给它的值是虚值,可以省略该属性。
var InputComponent = React.createClass({
render: function() {
var required = true;
var disabled = false;

return(
  <input type="text" disabled={disabled} required={required}>
)
1
2
3
}
})
渲染结果:

另一种可能的方法是:
var condition = true;

var component = (

有状态组件、无状态组件
区分有状态和无状态组件?
有状态组件 无状态组件
1、在内存中存储有关组件状态变化的信息 1、计算组件的内部的状态
2、有权改变状态 2、无权改变状态
3、包含过去、现在和未来可能的状态变化情况 3、不包含过去、现在和未来可能的状态变化情况
4、接收无状态组件状态变化要求的通知,然后将props发送给他们 4、从有状态组件接收props并将其视为回调函数

对有状态组件和无状态组件的理解及使用场景
一、有状态组件
1、特点:
● 是类组件
● 有继承
● 可以使用this
● 可以使用react的生命周期
● 使用较多,容易频繁触发生命周期钩子函数,影响性能
● 内部使用 state,维护自身状态的变化,有状态组件根据外部组件传入的 props 和自身的 state进行渲染。
2、使用场景:
● 需要使用到状态的。
● 需要使用状态操作组件的(无状态组件的也可以实现新版本react hooks也可实现)
3、总结:
类组件可以维护自身的状态变量,即组件的 state ,类组件还有不同的生命周期方法,可以让开发者能够在组件的不同阶段(挂载、更新、卸载),对组件做更多的控制。类组件则既可以充当无状态组件,也可以充当有状态组件。当一个类组件不需要管理自身状态时,也可称为无状态组件。
二、无状态组件
1、特点:
● 不依赖自身的状态state
● 可以是类组件或者函数组件。
● 可以完全避免使用 this 关键字。(由于使用的是箭头函数事件无需绑定)
● 有更高的性能。当不需要使用生命周期钩子时,应该首先使用无状态函数组件
● 组件内部不维护 state ,只根据外部组件传入的 props 进行渲染的组件,当 props 改变时,组件重新渲染。
2、使用场景:
● 组件不需要管理 state,纯展示
3、优点:
● 简化代码、专注于 render
● 组件不需要被实例化,无生命周期,提升性能。输出(渲染)只取决于输入(属性),无副作用
● 视图和数据的解耦分离
4、缺点:
● 无法使用 ref
● 无生命周期方法
● 无法控制组件的重渲染,因为无法使用shouldComponentUpdate 方法,当组件接受到新的属性时则会重渲染
三、总结:
组件内部状态且与外部无关的组件,可以考虑用状态组件,这样状态树就不会过于复杂,易于理解和管理。当一个组件不需要管理自身状态时,也就是无状态组件,应该优先设计为函数组件。比如自定义的 、 等组件。

函数组件、类组件
函数组件(Functional component,也称哑组件,或展示组件,或hooks组件)和类组件(Class component)的相同点和不同点?(税友)
一、相同点:都可以接收props返回react元素
二、不同点:
● 编程思想:类组件需要创建实例,面向对象,函数组件不需要创建实例,接收输入,返回输出,函数式编程
● 内存占用:类组建需要创建并保存实例,占用一定的内存
● 值捕获特性:函数组件具有值捕获的特性 。function组件能捕获渲染的值(captaure the rendered values),读取渲染闭包内的数据,而class组件在react通过this.的方式读取,this是可变的,所以总能获取最新的props
● 状态:类组件有自己的状态,函数组件没有,只能通过useState。Class把state属性挂载的对象保存到memoizedState属性中,而Function是用链表来保存状态的,memoizedState属性保存是链表的头指针。
● 生命周期:类组件有完整生命周期,函数组件没有,可以使用useEffect实现类似的生命周期
● 可测试性:函数组件方便测试
● 逻辑复用:类组件继承 Hoc(逻辑混乱 嵌套),组合优于继承,函数组件hook逻辑复用
● 跳过更新:shouldComponentUpdate PureComponent,React.memo
● 发展未来:函数组件将成为主流,屏蔽this、规范、复用,适合时间分片和渲染

受控组件、非受控组件
何为受控组件(controlled component)?
React负责渲染表单的组件,值是来自于state控制的输入表单元素称为受控组件

你对受控组件和非受控组件了解多少? / 什么是受控组件? 什么是非受控组件?
● 受控组件是React控制中的组件,并且是表单数据真实的唯一来源。
● 非受控组件是由DOM处理表单数据的地方,而不是在React组件中。
尽管非受控组件通常更易于实现,因为只需使用refs即可从DOM中获取值,但通常建议优先选择受控制的组件,而不是非受控制的组件。
这样做的主要原因是受控组件支持即时字段验证,允许有条件地禁用/启用按钮,强制输入格式。
受控组件 非受控组件
1、没有维持自己的状态 1、保持着自己的状态
2、数据由父组件控制 2、数据由dom控制
3、通过props获取当前值,然后通过回调通知更改 3、refs用于获取当前值

props
区分状态(state)和 属性(props)?/ (组件的)状态(state)和属性(props)之间有何不同?
● Props是一个从外部传进组件的参数,主要作用就是父组件向子组件传递数据,但是props对于使用它的组件来说是只读的,一旦赋值不能修改,只能通过外部组件主动传入新的props来重新渲染子组件
● State 一个组件的显示形态可以由数据状态和外部参数决定,外部参数是props,数据状态就是state,首先,在组件初始化的时候,用this.state给组件设定一个初始的state,在第一次渲染的时候就会用这个数据来渲染组件,state不同于props一点是,state可以修改,通过this.setState()方法来修改state
条件 state props
从父组件中接收初始值 yes yes
从父组件可以改变值 no yes
在组件中设置默认值 yes yes
在组件的内部变化 yes no
设置子组件的初始值 yes yes
在子组件的内部更改 no yes

纯函数
什么是纯函数?
纯函数是不依赖并且不会在其作用域之外修改变量状态的函数。本质上,纯函数始终在给定相同参数的情况下返回相同结果。

state
React中的状态是什么?它是如何使用的?
状态是 React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行为的对象。与props 不同,它们是可变的,并创建动态和交互式组件。可以通过 this.state() 访问它们。

如何更新组件的状态
this.setState()、useState

当调用setState时,React render是如何工作的?
可以将render分为两个步骤
● 虚拟DOM渲染:当render方法被调用时,它返回一个新的组件的虚拟DOM结构。当调用setState()时,render会被再次调用,因为默认情况下shouldComponentUpdate总是返回true,所以默认情况下React是没有优化的。
● 原生DOM渲染:React只会在虚拟DOM中修改真实DOM节点,而且修改的次数非常少——这是很棒的React特性,它优化了真实DOM的变化,使React变得更快。

setState
调用 setState 之后发生了什么?
React在调用setstate后,react会将传入的参数对象和组件当前的状态合并,触发调和过程,
在调和过程中,react会根据新的状态构建react元素树重新渲染整个UI界面,在得到元素树之后,react会自动计算新老节点的差异,根据差异对界面进行最小化重新渲染

setState是同步的还是异步的?
一、setState 并不是单纯同步/异步的,它的表现会因调用场景的不同而不同:
● 在 React 钩子函数及合成事件中,它表现为异步;
● 同步:
○ DOM 原生事件中(绕过React通过addEventListener直接添加的事件处理函数)
○ 通过setTimeout/setInterval产生的异步调用
二、这种差异,本质上是由 React 事务机制和批量更新机制的工作方式来决定的:在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。

为什么建议传递给 setState 的参数是一个 callback 而不是一个对象
因为在setstate中,props和state可能会异步更新,也就是说,对相同的变量进行处理的时候,会将这多次处理合并为一个,这个是批处理;而如果传入函数,那么会进行链式调用,这个函数会被react加入到一个执行队列中,函数中的代码会依次执行。


● useRef
React中可以在render访问refs吗?为什么?
不可以,render 阶段 DOM 还没有生成,无法获取 DOM。DOM 的获取需要在 pre-commit 阶段和 commit 阶段。

组件通信
父子组件通信?
● 正向传值:父组件 -> 子组件
○ props
● 逆向传值:子组件 -> 父组件
○ props + 回调
● 订阅-发布
● redux

跨级组件方式?
● 逐层传值
○ 父 -> 子 -> 孙…,通过props往下传,通过回调往上传
● 跨级传值
○ context
● 订阅-发布
● redux

兄弟组件通信方式?
● 通过兄弟节点的共同父节点,由父节点转发消息
● 浏览器存储:使用sessionStorage、localStorage
● 路由传值:如果两个组件之间存在跳转,可以使用路由跳转赋值
● 订阅-发布
● redux


React 中 key 的作用是什么?

key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。

当组件刷新时,React 内部会根据 key 和元素的 type,来对比元素是否发生了变化。若选做 key 的数据有问题,可能会在更新的过程中产生异常。

猜你喜欢

转载自blog.csdn.net/weixin_66709443/article/details/131958342