React常见面试题 ( 二 )

本文深入探讨了React中的关键概念,包括VirtualDOM的工作原理,AJAX调用的最佳实践,React Router v4的组件使用,以及Redux中间件的功能。同时,文章还讨论了React性能优化策略,生命周期函数的作用,以及如何正确发起Ajax请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Virtual DOM 如何工作?

Virtual DOM 分为三个简单的步骤。

  • 每当任何底层数据发生更改时,整个 UI 都将以 Virtual DOM 的形式重新渲染。
    在这里插入图片描述
  • 然后计算先前 Virtual DOM 对象和新的 Virtual DOM 对象之间的差异。
    在这里插入图片描述
  • 一旦计算完成,真实的 DOM 将只更新实际更改的内容。
    -在这里插入图片描述

2.如何发起 AJAX 调用以及应该在哪些组件生命周期方法中进行 AJAX 调用?

你可以使用 AJAX 库,如 Axios,jQuery AJAX 和浏览器内置的 fetch API。你应该在 componentDidMount() 生命周期方法中获取数据。这样当获取到数据的时候,你就可以使用 setState() 方法来更新你的组件。

例如,从 API 中获取员工列表并设置本地状态:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      employees: [],
      error: null
    }
  }

  componentDidMount() {
    fetch('https://api.example.com/items')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            employees: result.employees
          })
        },
        (error) => {
          this.setState({ error })
        }
      )
  }

  render() {
    const { error, employees } = this.state
    if (error) {
      return <div>Error: {error.message}</div>;
    } else {
      return (
        <ul>
          {employees.map(item => (
            <li key={employee.name}>
              {employee.name}-{employees.experience}
            </li>
          ))}
        </ul>
      )
    }
  }
}

3.在 React Router v4 中的组件是什么?

React Router v4 提供了以下三种类型的 组件:

  • < BrowserRouter >
  • < HashRouter >
  • < MemoryRouter >

以上组件将创建browser,hash和memory的 history 实例。React Router v4 通过router对象中的上下文使与您的路由器关联的history实例的属性和方法可用。

4.history 中的 push() 和 replace() 方法的目的是什么?

一个 history 实例有两种导航方法:

  • push()
  • replace()

如果您将 history 视为一个访问位置的数组,则push()将向数组添加一个新位置,replace()将用新的位置替换数组中的当前位置。

5.如何使用在 React Router v4 中以编程的方式进行导航?

在组件中实现操作路由/导航有三种不同的方法。

1.使用withRouter()高阶函数:
withRouter()高阶函数将注入 history 对象作为组件的 prop。该对象提供了push()和replace()方法,以避免使用上下文。

import { withRouter } from 'react-router-dom' // this also works with 'react-router-native'

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    {'Click Me!'}
  </button>
))

2.使用组件和渲染属性模式:
组件传递与withRouter()相同的属性,因此您将能够通过 history 属性访问到操作历史记录的方法。

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history }) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      {'Click Me!'}
    </button>
  )} />
)

3.使用上下文:
建议不要使用此选项,并将其视为不稳定的API。

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      context.history.push('/new-location')
    }}
  >
    {'Click Me!'}
  </button>
)

Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

6.为什么你会得到 “Router may have only one child element” 警告?

此警告的意思是Router组件下仅能包含一个子节点。

你必须将你的 Route 包装在 块中,因为 是唯一的,它只提供一个路由。

首先,您需要在导入中添加Switch:

import { Switch, Router, Route } from 'react-router'

然后在 块中定义路由:

<Router>
  <Switch>
    <Route {/* ... */} />
    <Route {/* ... */} />
  </Switch>
</Router>

7.如何在 React Router v4 中将 params 传递给 history.push 方法?

在导航时,您可以将 props 传递给history对象:

this.props.history.push({
  pathname: '/template',
  search: '?name=sudheer',
  state: { detail: response.data }
})

search属性用于在push()方法中传递查询参数。

8.如何实现默认页面或 404 页面?

< Switch>呈现匹配的第一个孩子。 没有路径的总是匹配。所以你只需要简单地删除 path 属性,如下所示:

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/user" component={User}/>
  <Route component={NotFound} />
</Switch>

9.redux中间件

中间件提供第三方插件的模式,自定义拦截 action -> reducer 的过程。变为 action -> middlewares -> reducer 。这种机制可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能
常见的中间件:

  • redux-logger:提供日志输出
  • redux-thunk:处理异步操作
  • redux-promise:处理异步操作,actionCreator的返回值是promise

10.redux有什么缺点

1.一个组件所需要的数据,必须由父组件传过来,而不能像flux中直接从store取。
2.当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,可能会有效率影响,或者需要写复杂的shouldComponentUpdate进行判断。

11.react生命周期函数

在此推荐一个博客,关于react生命周期写的很详细 【超级吴小迪 react生命周期】

这个问题要考察的是组件的生命周期

一、初始化阶段:
getDefaultProps:获取实例的默认属性
getInitialState:获取每个实例的初始化状态
componentWillMount:组件即将被装载、渲染到页面上
render:组件在这里生成虚拟的DOM节点
componentDidMount:组件真正在被装载之后

二、运行中状态:
componentWillReceiveProps:组件将要接收到属性的时候调用
shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态
render:组件重新描绘
componentDidUpdate:组件已经更新

三、销毁阶段:
componentWillUnmount:组件即将销毁

12.react性能优化方案

(1)重写shouldComponentUpdate来避免不必要的dom操作。
(2)使用 production 版本的react.js。
(3)使用key来帮助React识别列表中所有子组件的最小变化。

13.(在构造函数中)调用 super(props) 的目的是什么

在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props

14.应该在 React 组件的何处发起 Ajax 请求

在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络请求将保证这有一个组件可以更新了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值