面试题 之 react

时间:2024-03-30 08:33:21

1.说说对react的理解

1️⃣是什么
React是用于构建用户界面的 JavaScript 库,遵循组件设计模式、声明式编程范式和函数式编程概念,更高效使用虚拟 DOM 来有效地操作 DOM ,遵循从高阶组件到低阶组件的单向数据流。
react 类组件使用一个名为 render() 的方法或者函数组件 return ,接收输入的数据并返回需要展示的内容。形式就是JSX,最终会babel被编译为合法的 JS语句调用,被传入的数据可在组件中通过this.props 在render() 访问。
2️⃣特性
JSX 语法
单向数据绑定
虚拟 DOM
声明式编程
Component
3️⃣优势
高效灵活
声明式的设计,简单使用
组件式开发,提高代码复用率单向响应的数据流会比双向绑定的更安全,速度更快

2.state和props区别

1️⃣state
一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是 state ,一般在 constructor 中初始化,当需要修改里面的值的状态需要通过调用 setState 来改变。
setState 还可以接受第二个参数,它是一个函数,会在 setState 调用完成并且组件开始重新演染时被调用,可以用来监听渲染是否完成
2️⃣props
props理解为从外部传入组件内部的数据,react 具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据。props 可以传字符串,数字,传递对象,数组,回调函数。
props 在内部不可变的,如果想要改变它看,只能通过外部组件传入新的 props 来重新渲染子组件,否则子组件的 props 和展示形式不会改变
3️⃣区别
相同点:
两者都是 JavaScript 对象
两者都是用于保存信息
props 和state 都能触发渲染更新
区别:
props 是外部传递给组件的,而 state 是在组件内被组件自己管理的,一般在 constructor 中初始化
props 在组件内部是不可修改的,但state 在组件内部可以进行修改,state 是多变的、可以修改

3.super()和super(props)区别

在React 中,类组件基于ES6,所以在 constructor 中必须使用 super在调用 super 过程,无论是否传入 props,React 内部都会将 porps赋值给组件实例porps 属性中如果只调用了 super(),那么 this.props 在super() 和构造函数结束之间仍是undefined

4.说说对react中类组件和函数组件的理解?

1️⃣类组件
通过使用 ES6 类的编写形式来编写组件,该类必须继承 React.Component
如果想要访问父组件传递过来的参数,可通过this.props 的方式去访问,在组件中必须实现render 方法,在return 中返回 React 对象
2️⃣函数组件
通过函数编写的形式去实现一个 React 组件。
函数第一个参数为props用于接收父组件传递过来的参数
3️⃣区别
1.编写形式:一个function,一个class
2.状态管理:
类组件中调用setState,在 hooks 情况下,函数组件调用 state ,则需要创建一个类组件或者 state 提升到父组件中,然后通过props 对象传递到子组件
3.生命周期:
在函数组件中不存在生命周期,生命周期钩子来自于继承的react.Component,函数组件useEffect来对应类组件中的componentDidMount生命周期。useEffect回调函数中return一个函数,则return函数会在组件卸载的时候执行,正如componentWillUnmount
4.调用方式:
函数组件调用则是执行函数
类组件则需要将组件进行实例化,然后调用实例对象的render方法
5.获取渲染值:
类组件中输出this.props.user,this总是可变的,而函数组件本身不存在this
4️⃣总结
两种组件都有各自的优缺点
函数组件语法更短,更简单,而类组件会因大量使用this而让人感到困惑

5.说说对受控组件和非受控组件的理解?应用场景?

受控组件:就是受我们控制的组件,组件的状态全程响应外部数据,受控组件需要初始状态和状态更新事件函数。
非受控组件:初始化接受外部数据,自己在内部存储其自身状态,通过ref查询DOM并查找其当前值。
应用场景:
大部分时候推荐使用受控组件来实现表单
在这里插入图片描述

6.说说react的事件机制?

react基于浏览器的事件机制自身实现了一套事件机制,包括事件注册,事件合成,事件冒泡,事件派发等,在react中这套事件机制被称为合成事件。
react事件机制总结:
React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少
内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
React 自身实现了一套事件冒泡机制,所以这也就是为什么我们event.stopPropagation()无效的原因。
React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callbackReact 有一套自己的合成事件SyntheticEvent

7.react事件绑定的方式有哪些?区别?

绑定方式:
render方法中使用bind
render方法中使用箭头函数
constructor中bind
定义阶段使用箭头函数绑定

区别:
编写方面:方式一、方式二写法简单,方式三的编写过于冗杂;
性能方面:方式一和方式二在每次组件render的时候都会生成新的方法实例,性能问题欠缺。若该函数作为属性值传给子组件的时候,都会导致额外的渲染。而方式三、方式四只会生成一个方法实例;
综合上述,方式四是最优的事件绑定方式。

8.react构建组件的方式有哪些?区别?

构建方式:
函数式创建
通过React.createClass 方法创建
继承 React.Component 创建
区别:
由于React.createclass创建的方式过于冗杂,并不建议使用而像函数式创建和类组件创建的区别主要在于需要创建的组件是否需要为有状态组件:·
对于一些无状态的组件创建,建议使用函数式创建的方式
由于react hooks 的出现,函数式组件创建的组件通过使用 hooks 方法也能使之成为有状态组件,再加上目前推崇函数式编程,所以这里建议都使用函数式的方式来创建组件在考虑组件的选择原则上,能用无状态组件则用无状态组件

9.说说react中引入css的方式有哪几种?区别?

方式:
在组件内直接使用
组件中引入.css 文件
.module.css 文件
css in Js
区别:
在组件内直接使用css该方式编写方便,容易能够根据状态修改样式属性,但是大量的演示编写
在组件内直接使用容易导致代码混乱;
组件中引入.css 文件符合我们日常的编写习惯,但是作用域是全局的,样式之间会层叠引;
引入.module.css 文件能够解决局部作用域问题,但是不方便动态修改样式,需要使用内联的方式进行样式的编写;
通过cssin s 这种方法,可以满足大部分场景的应用,可以类似于预处理器一样样式嵌套、定义修改状态等;
至于使用 react 用哪种方案引入 css ,并没有一个绝对的答案,可以根据各自情况选择合适的方案

10.说说react生命周期有哪些不同阶段?每个阶段对应的方法是?

三个阶段:
创建阶段
constructor
getDerivedStateFromProps
render
componentDidMount
更新阶段
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
卸载阶段
componentWillUnmount

11.react中组件之间如何通信?

父组件向子组件传递:
由于react的数据流动为单向的,父组件向子组件传递是最常见的方式,父组件在调用子组件的时候,只需要在子组件标签哪传递参数,子组件通过props属性就能接收父组件传递过来的参数

子组件向父组件传递:
父组件向子组件传一个函数,然后通过这函数的回调,拿到子组件传过来的值

兄弟组件之间的通信:
父组件作为中间层来实现数据的互通,通过使用父组件传递

父组件向后代组件传递:
通过使用react.createContext创建一个context,创建成功后,存在provider组件通过value属性用于给后代组件传递数据,通过consumer组件或者使用contextType属性接收

非关系组件传递:
通过使用redux

总结:
由于 React 是单向数据流,主要思想是组件不会改变接收的数据,只会监听数据的变化,当数据发生变化时它们会使用接收到的新值,而不是去修改已有的值因此,可以看到通信过程中,数据的存储位置都是存放在上级位置中

12.说说对高阶组件的理解?

在react中,高阶组件即接受一个或多个组件作为参数并且返回一个组件,本质就是一个函数,并不是一个组件。
通过对传入的原始组件做一些你想要的操作(比如操作 props,提取 state,给原始组件包裹其他元素等),从而加工出想要的组件把通用的逻辑放在高阶组件中,对组件实现一致的处理,从而实现代码的复用所以,高阶组件的主要功能是封装并分离组件的通用逻辑,让通用逻辑在组件间更好地被复用

使用高阶组件的同时,一般遵循一些约定,如下:
props 保持一致
不能在函数式组件上使用 ref 属性,因为没有实例
不要再render()方法中使用高阶组件
使用 compose 组合高阶组件

应用场景
高阶组件能够提高代码的复用性和灵活性,在实际应用中,常常用于与核心业务无关但又在多个模块使用的功能,如权限控制、日志记录、数据校验、异常处理、统计上报等

13.在react中组件间过渡动画如何实现?

在react 中实现过渡动画效果如:
react-transition-group
react-motion
Animated
原生的CSS

14.说说你在react项目中如何捕获错误的?

错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误形成错误边界组件的两个条件:
使用了 static getDerivedStateFromError().
使用了 componentDidCatch()

下面这些情况无法捕获到异常:
事件处理
异步代码
服务端渲染
自身抛出来的错误
对于错误边界无法捕获的异常,如事件处理过程中发生问题并不会捕获到,是因为其不会在渲染期间触发,并不会导致渲染时候问题
这种情况可以使用js 的try…catch…语法

15.说说对react里的refs的理解?应用场景?

React 中的Refs 提供了一种方式,允许我们访问DOM 节点或在 render方法中创建的React元素本质为 ReactDOM.render() 返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom 则返回的是具体的dom 节点

使用:
创建ref 的形式有三种:
传入字符串,使用时通过 this.refs传入的字符串的格式获取对应的元素
传入对象,对象是通过 React.createRef()方式创建出来,使用时获取到创建的对象中存在current 属性就是对应的元素
传入函数,该函数会在 DOM 被挂载时进行回调,回调函数参数会传入一个 元素对象,然后通过实例将对象进行保存
传入hook,hook是通过useRef() 方式创建,使用时通过生成hook对象的 current 属性就是对应的元素

应用场景:
对Dom元素的焦点控制、内容选择、控制
对Dom元素的内容设置及媒体播放对Dom元素的操作和对组件实例的操作
集成第三方 DOM 库