React面试频率比较高的题型3

1.props和state的相同点和不同点?render的执行时机?

相同点:
1. 两者都是React组件中用于存储和管理数据的机制。
2. 无论是props还是state,都可以用来渲染组件的内容。

不同点:
1. props是父组件传递给子组件的数据,而state是组件自身管理的数据。
2. props是只读的,子组件不能直接修改props的值,而state是可变的,组件可以通过setState方法来修改state的值。
3. props的值由父组件确定,而state的值是在组件内部初始化并管理的。
4. 当props的值发生变化时,组件会重新渲染,而state的变化只会引起组件的局部更新。

render的执行时机:
render方法是React组件中必须实现的方法,用于渲染组件的内容。它在以下情况下执行:
1. 组件首次渲染时,会执行一次render方法来生成组件的初始DOM结构。
2. 当组件的props或state发生变化时,会触发重新渲染,即执行render方法来更新组件的内容。
3. 当调用组件的forceUpdate方法时,会强制触发重新渲染,即执行render方法来更新组件的内容。


2.shouldComponentUpdate有什么作用?

        (1)shouldComponentUpdate(nextProps,nextState) 接受两个参数分别表示:

        nextProps:表示下一个props                 nextState:表示下一个state的值
        根据shoudldComponentUpdate()的返回值去判断React组件的输出是否跟新,如果组件返回          ture则更新组件 如果组件返回false 组件不更新    默认行为使state每次发生变化组件都会重新渲染

shouldComponentUpdate(nextProps, nextState){
    //组件是否需要更新,需要返回一个布尔值,返回true则更新,返回flase不更新,这是一个关键点
    console.log('shouldComponentUpdate组件是否应该更新,需要返回布尔值',nextProps, nextState)
    return true
}


注:当props或state发生变化时,shouldComponentUpdate会在渲染执行之前被调用,返回值默认为true,首次渲染或使用forceUpdate时不会调用该方法。

(2)性能优化

React提供了生命周期函数shouldComponentUpdate(),根据它的返回值 true  false,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。
shouldComponentUpdate方法接收两个参数nextProps和nextState,可以将this.props与nextProps以及this.state与nextState进行比较,并返回 false 以告知 React 可以跳过更新。

shouldComponentUpdate (nextProps, nextState) {
  return true
}

我们已经知道了shouldComponentUpdate函数的作用,下面我们在组件中添加代码:

shouldComponentUpdate(nextProps, nextState) {
    return this.props.son !== nextProps.son
}

这个时候再点击按钮修改父组件 state 中的值时,组件就不会再重新渲染了。


3.说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关 系

在React中,虚拟DOM(Virtual DOM)是一种轻量级的JavaScript对象表示真实DOM的结构。它是React用来提高性能的一种机制。

虚拟DOM的工作原理如下:
1. 当组件的状态发生变化时,React会创建一个新的虚拟DOM树。
2. React会将新的虚拟DOM树与旧的虚拟DOM树进行比较,找出两者之间的差异。
3. 根据差异,React会生成一系列更新操作,然后将这些操作应用到真实的DOM上,只更新需要更新的部分。

在虚拟DOM计算的过程中,diff算法和key属性之间有以下关系:
1. diff算法是用于比较新旧虚拟DOM树之间的差异的算法,它会找出需要更新的节点以及新增、删除和移动的节点。
2. key是用于帮助React识别组件的唯一标识符,它在虚拟DOM的diff算法中起到了优化的作用。
3. 当React进行虚拟DOM的比较时,如果没有为节点提供key属性,React会使用节点在数组中的索引作为默认的key值。
4. 如果在更新过程中,节点的key发生了变化,React会将该节点视为一个新的节点,而不是进行更新操作,这样可以避免不必要的DOM操作,提高性能。

总结来说,key属性在虚拟DOM的diff算法中起到了优化的作用,它可以帮助React更准确地识别组件的变化,从而减少不必要的DOM操作。使用合适的key值可以提高React的性能。


4.react生命周期新出来两个钩子函数是什么?和删掉的will系列有什么区别

React生命周期新出来的两个钩子函数是getDerivedStateFromProps和getSnapshotBeforeUpdate。

1. getDerivedStateFromProps:是一个静态方法,用于在组件接收到新的props时更新state。它接收两个参数,props和state,并且必须返回一个对象来更新state,或者返回null表示不需要更新state。相当于替代了旧的componentWillReceiveProps生命周期函数。

2. getSnapshotBeforeUpdate:用于在组件更新之前获取DOM的快照。它接收两个参数,prevProps和prevState,并且可以返回一个值。该值会作为第三个参数传递给componentDidUpdate生命周期函数。通常用于在组件更新前保存一些DOM状态,然后在componentDidUpdate中进行比较或处理。相当于替代了旧的componentWillUpdate生命周期函数。

区别:
- getDerivedStateFromProps和will系列生命周期函数的主要区别在于使用方式和语法上的差异。getDerivedStateFromProps是一个静态方法,可以直接在组件类中定义,不需要继承React.Component。而will系列生命周期函数需要在类组件中定义,并且需要继承React.Component。
- getDerivedStateFromProps是一个静态方法,它没有访问组件实例的this,因此不能访问组件的实例属性和方法。而will系列生命周期函数可以通过this访问组件的实例属性和方法。
- getDerivedStateFromProps只能通过返回一个对象来更新state,或者返回null表示不需要更新state。而will系列生命周期函数可以通过调用this.setState来更新state。
- getDerivedStateFromProps在组件初始化和每次接收到新的props时都会被调用,而will系列生命周期函数只在特定的生命周期阶段被调用。
- getSnapshotBeforeUpdate在组件更新之前被调用,可以获取到更新前的DOM状态。而will系列生命周期函数在组件更新之后被调用,无法获取到更新前的DOM状态。


5.React的props.children使用map函数来遍历会收到异常显示,为什么?应该如何遍历

如果使用map函数来遍历React的props.children时收到异常显示,可能是因为props.children不是一个数组,而是一个特殊的数据类型。

React的props.children可以是任意类型的数据,包括字符串、数字、React元素、数组等。当props.children只有一个元素时,它是一个单独的React元素。当props.children有多个元素时,它是一个包含这些元素的数组。

因此,如果要遍历props.children,需要先判断它的类型,然后根据类型进行相应的处理。

下面代码是一种常见的遍历props.children的方式:

{React.Children.map(props.children, (child, index) => {
  // 处理每个子元素
  return (
    // 返回处理后的子元素
  );
})}

在上面的代码中,使用React.Children.map函数来遍历props.children。这个函数会对props.children进行处理,并返回一个新的数组。

注意,React.Children.map函数会自动过滤掉props.children中的null、undefined和布尔值等无效的元素。

另外,如果props.children只有一个元素,也可以直接对它进行操作,而不需要使用map函数。例如:

const child = React.Children.only(props.children);
// 对child进行操作

在上面的代码中,使用React.Children.only函数来获取props.children中的唯一元素,并将其赋值给变量child。然后可以对child进行操作。

总结起来,遍历React的props.children时,需要根据其类型进行相应的处理,可以使用React.Children.map函数来遍历多个元素,或者使用React.Children.only函数来操作单个元素。


6.谈谈你对immutable.js的理解

Immutable.js是一个用于创建和操作不可变数据的JavaScript库。它提供了一系列的数据结构,如List、Map、Set等,这些数据结构都是不可变的,即一旦创建就不能被修改。

不可变数据的特点是它们的值不能被改变,而是通过创建新的数据来表示修改后的状态。这种不可变性有一些优势:

1. 简化复杂的状态管理:由于不可变数据是不可变的,所以可以轻松地进行时间旅行和撤销/重做操作。这对于复杂的应用程序状态管理非常有用。

2. 提高性能:由于不可变数据是不可变的,可以使用结构共享来减少内存占用和提高性能。当修改不可变数据时,实际上是在创建一个新的数据结构,而共享之前的数据结构。这样可以避免复制整个数据结构,节省内存和提高性能。

3. 减少Bug的可能性:由于不可变数据是不可变的,可以避免因为数据被意外修改而引起的副作用。这样可以减少Bug的产生和调试的复杂性。

使用Immutable.js可以通过以下方式创建和操作不可变数据:

1. 创建不可变数据:使用Immutable.js提供的数据结构,如List、Map、Set等来创建不可变数据。

2. 获取数据:使用Immutable.js提供的方法来获取不可变数据的值,如get、getIn等。

3. 修改数据:使用Immutable.js提供的方法来修改不可变数据,如set、update等。这些方法会返回一个新的不可变数据,而不会修改原始数据。

4. 比较数据:使用Immutable.js提供的方法来比较不可变数据的值,如equals、is等。

总的来说,Immutable.js提供了一种方便、高效、可靠的方式来处理不可变数据,可以帮助我们更好地管理和操作复杂的应用程序状态。它在React和Redux等前端框架中广泛应用,可以提高应用的性能和可维护性。


7.redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么

Redux本身是一个同步的状态管理库,它的核心是通过纯函数来处理状态的变化。然而,在实际应用中,我们经常需要处理异步操作,例如发送网络请求或者定时器等。为了支持这些异步操作,Redux引入了中间件的概念。

中间件是Redux的一个扩展机制,它允许我们在action被发起之后,到达reducer之前,对action进行拦截和处理。通过中间件,我们可以在Redux的流程中执行异步操作,并在异步操作完成后再派发一个新的action来更新状态。

Redux中间件的实现原理是基于函数的柯里化和高阶函数的概念。一个Redux中间件是一个函数,它接收Redux的store作为参数,并返回一个函数,这个返回的函数接收下一个中间件或者最终的dispatch函数作为参数。这个返回的函数也可以称为中间件的“洋葱模型”,因为它会在处理action的过程中,逐层包裹和执行中间件。

当我们使用中间件时,Redux会将每个中间件按照顺序串联起来,并将最终的dispatch函数作为参数传递给第一个中间件。当我们派发一个action时,这个action会依次经过每个中间件的处理。每个中间件都可以对action进行拦截、修改或者延迟处理,然后将处理后的action传递给下一个中间件,直到最终到达reducer。

中间件的实现原理可以通过以下伪代码来理解:

function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, initialState) => {
    const store = createStore(reducer, initialState);
    let dispatch = store.dispatch;

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    };

    const chain = middlewares.map((middleware) => middleware(middlewareAPI));
    dispatch = compose(...chain)(store.dispatch);

    return {
      ...store,
      dispatch
    };
  };
}

在上面的代码中,applyMiddleware函数接收一组中间件作为参数,并返回一个新的函数。这个新的函数接收createStore函数作为参数,并返回一个新的函数。这个新的函数接收reducer和initialState作为参数,并返回一个包含了增强功能的store对象。

在这个过程中,中间件被串联起来,并通过compose函数进行组合。每个中间件都接收一个middlewareAPI对象作为参数,这个对象包含了getState和dispatch方法。中间件可以通过这些方法来获取当前的状态和派发新的action。

总结起来,Redux中间件的实现原理是基于函数的柯里化和高阶函数的概念。通过中间件,我们可以在Redux的流程中执行异步操作,并对action进行拦截、修改或者延迟处理。这个机制使得Redux可以处理复杂的异步操作,提供了更灵活和可扩展的状态管理方案。


8.在使用redux过程中,如何防止定义的action-type的常量重复

在Redux中,我们通常会定义一些action-type的常量来表示不同的action类型。这些常量用于定义action的type字段,以便在reducer中根据不同的action类型来处理状态的变化。

为了防止定义的action-type常量重复,可以考虑以下几个方法:

1. 命名规范:在定义action-type常量时,可以遵循一定的命名规范,例如使用全大写字母、下划线等来分隔单词。这样可以增加常量的可读性,并减少命名冲突的可能性。

2. 命名空间:可以为不同的模块或者功能定义不同的命名空间,以避免不同模块之间的命名冲突。可以在定义action-type常量时,加上相应的前缀或者命名空间,以示区分。

3. 使用工具库:可以使用一些工具库来帮助管理和生成action-type常量。例如,可以使用`redux-actions`库中的`createActions`方法来自动生成action-type常量,避免手动定义和管理。

4. 统一管理:可以将所有的action-type常量集中放在一个文件中进行统一管理。可以创建一个单独的文件,例如`constants.js`,在该文件中定义所有的action-type常量,并导出供其他文件使用。

通过以上的方法,可以有效地防止定义的action-type常量重复,并提高代码的可维护性和可读性。同时,建议在团队开发中进行代码审查和命名规范的约定,以确保所有成员都遵循相同的规范。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值