2023年前端 React 25道常见面试题汇总

1,说说 react 里面 bind 函数与箭头函数

bind 由于在类中,采用的是严格模式,所以事件回调的时候会丢失 this 指向,指向的 undefined,需要使用 bind 来给函数绑定上当前实例的 this 指向。

箭头函数的 this 指向上下文,所以永久能拿到当前组件实例的。this 指向我们可以完美的使用箭头函数来替代传统事件处理函数的回调。

2,说出几点 React 中的性能优化
  • 使用 shouldComponentUpdate 来对 state 和 props 进行对比,如果两次的结果一样,那么就 return false;

  • 使用纯函数组件 pureComponent;

3,简单解释下高阶组件和高阶函数
  • 高阶函数,指的是函数接收一个函数作为参数,或者将函数作为返回值的函数就是高阶函数 。

  • 高阶组价,接受一个组件,并返回一个新组建的组件就是高阶组件,本质上和高阶函数的意思一样的,高阶组件是用来复用 react 代码的一种方式。

4,setState 和 repalceState 有什么区别
  • setState 是修改其中的部分状态,相当于 Object. assign,只是覆盖,不会减少原来的状态。

  • replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象,如果新状态属性减少,那么 state 中就没有这个状态了。

5,Redux 中核心组件有哪些,reducer 的作用

Redux 由 Action、Reducer 和 Store 三部分构成,他们的解释如下:

  • action:action 理解为动作,action 的值一般为一个对象,格式如 {type: “”, data:“”},type 是必须要的,因为 reducer 处理数据的时候要根据不同的 type 来进行不同的操作。

  • reducer:reducer 是初始化以及处理派发的 action 的纯函数。

  • store:store 是一个仓库,用来存储数据,它可以获取数据,也可以派发数据,还能监听到数据的变化。
    而 reducer 的作用就是接收旧的 state 和 action,返回新的 state。

6,什么是受控组件

受控组件就是可以被 react 状态控制的组件。在 react 中,Input textarea 等组件默认是非受控组件(输入框内部的值是用户控制,和 React 无关)。但是也可以转化成受控组件,就是通过 onChange 事件获取当前输入内容,将当前输入内容作为 value 传入,此时就成为受控组件。

7,hooks+context 和 redux 你是怎么选择的,都在什么场景下使用

如果项目体量较小,只是需要一个公共的 store 存储 state,而不讲究使用 action 来管理 state,那 context 完全可以胜任。反之,则是 redux 的使用场景。

在进行状态管理时,通常遵循以下的原则:

  • 如果你在组件间传递的数据逻辑比较复杂,可以使用 redux;

  • 如果组件层级不多,可以使用 props;

  • 如果层级较深,数据逻辑简单,可以使用 context。

8,使用 useffect 模拟生命周期
  • 模拟 componentDidMount。第二个参数为一个空数组,可以模拟 componentDidMount,示例如下。
componentDidMount:useEffect(()=>{console.log('第一次渲染时调用')},[]) 


  • 模拟 componentDidUpdate。没有第二个参数代表监听所有的属性更新,示例如下。
useEffect(()=>{console.log('任意状态改变')})  


如果需要监听多个属性的变化则需要将属性作为数组传入第二个参数。

useEffect(()=>{console.log('指定状态改变')},[状态1,状态2...])  


  • 模拟 componentWillUnmount
useEffect(()=>{   ...  return()=>{ //组件卸载前}   }) 


9,setsate 和 usestate 的区别
  • setState(updater [,callback] ):构造函数是唯一建议给 this.state 赋值的地方,不建议直接修改 state 的值,因为这样不会重新渲染组件,自动进行浅合并(只会合并第 1 层),由于 setState() 异步更新的缘故,依赖 state 旧值更新 state 的时候建议采用传入函数的方式。

  • useState(initState):setState(updater) 用于修改状态的方法,updater:object/function 用于更新数据,initState 用于状态的初始值。

10,如何监听 react 父组件 props 变化。

当 props 发生变化时执行,初始化 render 时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用 this.setState() 来更新你的组件状态,旧的属性还是可以通过 this.props 来获取, 这里调用更新状态是安全的,并不会触发额外的 render 调用。

componentWillReceiveProps(props) { 
        console.log(props) 
    this.setState({show: props.checked}) 
} 


11,usememo 的作用,以及怎么使用

返回一个 memoized 值。

把 “创建” 函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo。

如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。

你可以把 useMemo 作为性能优化的手段,但不要把它当成语义上的保证。将来,React 可能会选择 “遗忘” 以前的一些 memoized 值,并在下次渲染时重新计算它们,比如为离屏组件释放内存。先编写在没有 useMemo 的情况下也可以执行的代码 —— 之后再在你的代码中添加 useMemo,以达到优化性能的目的。

12,React 的 Component 和 Purecomponent 区别

Component 没有直接实现 shouldComponentUpdate 这个方法,但是 PureComponent 通过浅层的 Porps 和 state 的对比,内部实现了这个生命周期函数。

PureComponent 会跳过整个组件子树的 props 更新,要确保全部的子组件也是 pure 的形式。

Component 中需要手动执行的 shouldComponentUpdate 函数,在 PureComponent 中已经自动完成了(自动浅对比)。

PureComponent 不仅会影响本身,而且会影响子组件,所以 PureComponent 最好用在数据展示组件中。

PureCoponent 如果是复杂数据类型,这里会造成错误的显示(setState 浅复制更新,但是界面不会重新渲染)。

13,Hooks 相对于类有哪些优化

首先,我们来看一下类组件的一些缺点:

缺点 1:复杂且不容易理解的 “this”。

Hooks 解决方式:函数组件和普通 JS 函数非常相似,在普通 JS 函数中定义的变量、方法都可以不使用 “this.”,而直接使用该变量或函数,因此你不再需要去关心“this” 了。

缺点 2:组件数据状态逻辑不能重用

Hooks 解决方式:通过自定义 Hook,可以数据状态逻辑从组件中抽离出去,这样同一个 Hook 可以被多个组件使用,解决组件数据状态逻辑并不能重用的问题。

缺点 3:组件之间传值过程复杂

Hooks 解决方式:通过 React 内置的 useState()函数,可以将不同数据分别从 “this.state” 中独立拆分出去。降低数据复杂度和可维护性,同时解决类组件缺点三中 “内部 state 数据只能是整体,无法被拆分更细” 的问题。

通过 React 内置的 useEffect() 函数,将 componentDidMount、componentDidUpdate、componentWillUncount 3 个生命周期函数通过 Hook(钩子) 关联成 1 个处理函数,解决事件订阅分散在多个生命周期函数的问题。

14,Hooks 父组件怎么调用子组件的方法

父组件使用 useRef 创建一个 ref 传入 子组件 子组件需要使用。useImperativeHandle 暴露 ref 自定义的实例值给父组件,并且需要使用 forwardRef 包裹着。

15,React 通过什么方法修改参数?

类组件修改数据的方法, 通过 setState , 注意 setState 的修改方法有两种,而且它是异步的

函数组件修改方式通过自定义的方法。需要通过 useState , 例如。const [count,setCount] = useState(0)。

16,说说你对 react native 的了解

React native 基于 JavaScript 开发的一个 可以开发原生 app 的这么一个集成框架,它兼容开发 iOS 和 Android 能够实现一套代码,两个系统都能使用,方便维护,相比于 web 前端的 react ,react-native 更好的提供了一些调用手机硬件的 API, 可以更好的开发移动端,现在 react-native 它的生态环境也是越来越好,基本上可以完全实现原生开发,

但是现在好多的应用还是用它来套壳 (原生 + web 前端),用它来做有些路由,和框架的搭建,然后里面内容来使用前端的 react 来实现,这样一来让维护更方便,开发更快捷

17,React 的输入框输入文字就会触发 onchange,怎么拿到他最后输入的结果呢?

方法 1:通过受控组件,可以获取到 state 里面的值,获取修改结果,代码如下。

 class Home extends React.Component { 
    state = { 
        val:"" 
     } 
     //这是一个通用的写法,然后注意 name的值一定要与state定义的一直 
    changeInput = (e) =>{ 
        let {name,value} = e.target 
        this.setState({ 
           [name]:value 
       }) 
    } 
    render(){ 
       return <> 
         <input onChange="this.state.val" /> 
       </> 
    } 
 } 


方法 2:通过 ref 来获取里面的值。

class Home extends React.Component { 
  render(){ 
      //this.val 获取里面的真是dom 
      return <input ref={node=>this.val} /> 
   } 
} 


18,React 的 render 什么时候渲染

React 生命周期有三个阶段。 两个阶段都会执行 render 主要从更新和挂载两个阶段来讲,挂载阶段会执行一次,更新阶段主要会涉及 shouldComponentUpdate。

首先,我们看一下挂载阶段:

constructor(){} 
static getDerivedStateFromProps(){ 
   return {} 
 } 

render(){}  //挂载阶段会执行一次 
componentDidMount(){} 


接下来,我们看一下更新阶段:

static getDerivedStateFromProps(props, state){rerturn {}} 
shouldComponentUpdate(nextProps, nextState).{ 
     return Boolean  //注意如果 false 则 不向下执行 ,true的时候会执行render
} 

render() ..       


19,useEffect 的依赖为引用类型如何处理

useEffect 的依赖为引用类型的时候,可能会导致监听不出发,原因就是监听的统一个地址的时候,对象本身地址没变,所以监听的结果就是认为数据并没有改变从而不直接调用。

解决的方法有以下几点:

  • 如果数据是对象的话,可以监听对象的里面的值,值是基本类型,如果值改变了,那么可以监听执行;

  • 在去修改对象和数据的时候,使用参拷贝或者浅拷贝,这样地址发生改变可以监听执行;

  • 可以转成字符串,通过 JSON.stringify() , 监听字符串这样的,这样改变也会执行;

20,说一下 key 发生哪些变化会触发什么生命周期

React 的 key 值给组件作为唯一标识,类似身份证,当数组发生增删改查的时候可以通过这个 标识来去对比虚拟 dom 的更改前后,如果相同标识的数据或者属性没有改变的话,讲直接略过,对比有改变的然后直接改变此项。

如果给组件添加 key,如果 key 值改变的时候,组件将会触发如下的生命周期:

  • constructor

  • getDerivedStateFromProps()

  • render(){}

  • componentDidUpdate

21,说说 React 里面的 createPortal。

react.createPortal() 这个方法是来使用做弹窗 Modal 组件的, 在没有这个组件之前我们可以自己定义组件,然后去实现 Modal 效果。

const styles = { 
  modal: { 
    position: 'fixed', 
    top: 0, 
    left: 0, 
    right: 0, 
    bottom: 0, 
    backgroundColor: 'rgba(0,0,0,0.3)', 
    display: 'flex', 
    justifyContent: 'center', 
    alignItems: 'center' 
  } 
} 

class Modal extends Component { 
  constructor(props) { 
    super(props); 
  } 
  render() { 
    return ( 
      <div style={styles.modal}> 
        {this.props.children} 
      </div> 
    ); 
  } 
} 


react.createPortal 这个来制作弹窗组件,它 在 Modal 组件位置进行 fixed 定位,可以任意的挂载到某个 dom 元素上,使用后的管理更方便,但是注意需要预留 html 的挂载元素。

22,说一下 React 全家桶

真正意义上的 react 全家桶,其实指的是 react,react-dom,react-native。因为 react 核心库只是 vDom 的操作,无关 dom(dom 操作在 react-dom 中)——这意味着它天生就可以做到跨平台。

注意这里有误区,react-router,react-router-dom,react-dux 只是社区的一些使用较多的解决方案,事实上它们各有缺陷。

23,简单介绍下 fiber

React Fiber 是 React 框架的一种底层架构,为了改进 React 的渲染引擎,使其更加高效、灵活和可扩展而提供的。

传统上,React 使用一种称为堆栈调和递归算法来处理虚拟 DOM 的更新,这种方法在大型应用或者频繁更新的情况下可能会产生性能问题。React Fiber 则是基于一种增量渲染的思想,它将更新任务分解成小的、可中断的单元,使得 React 在更新时可以更灵活地控制和切换任务,提高应用的响应性。

React Fiber 的核心功能包括:

  • 增量渲染: React Fiber 将更新任务拆分成多个小任务单元(称为 “fiber”),并使用优先级调度器来处理这些任务,以提高响应性和用户体验。

  • 优先级调度: Fiber 引入了优先级概念,使 React 能够根据任务的优先级来决定任务的执行顺序,确保高优先级任务得到及时处理。

  • 中断与恢复: React Fiber 允许在渲染过程中中断任务,然后在适当的时机恢复执行,从而避免了阻塞的情况。

  • 任务取消: Fiber 具备任务取消的能力,可以取消不必要的更新,提高性能。

24,谈谈你对 Hooks 的理解

react-hooks 提供给了函数式组件以业务逻辑抽离封装的能力,从单一组件单位进行 UI 与业务逻辑的分离,以此来保证函数式组件的 UI 纯净。

Hooks 的出现解决了两个问题:

  • 组件的状态逻辑复用

  • class 组件自身的问题
    组件的逻辑复用:在 hooks 出现之前,react 先后尝试了 mixins 混入,HOC 高阶组件,render-props 等模式但是都有各自的问题,比如 mixin 的数据来源不清晰,高阶组件的嵌套问题等等

Class 组件自身的问题:class 组件本身提供了很多东西,有不可忽视的学习成本,比如各种生命周期,this 指向问题等等。

25,什么是副作用,聊聊 useEffect 的副作用,以及如何解决

副作用函数

我们将跟 UI 渲染无关的业务逻辑称之为副作用。

useEffect 是 react 在函数式组件里提供的副作用解决方案,它接受两个参数。第一个是必传参数,类型为函数。我们写在此函数中的业务逻辑代码就是我们所说的副作用。

消除副作用

默认情况下,useEffct 会在每次 render 后执行传入的副作用函数。然而有的时候我们需要在执行副作用前先去除掉上次 render 添加的副作用效果, 我们可以在副作用函数里再返回一个函数,这个函数就是消除副作用,它会在每次 reRender 前和组件卸载时去执行。

监听器

与 useMemo, useCallback 等一样,useEffect 可以传入一个监听数组参数,这意味着副作用只有在数组中的监听值变化时才会执行。借助它的这个参数特性,可以模拟类组件生命周期钩子,比如 componentDidMount 等。

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西江茶客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值