React面试整理

169 阅读5分钟

1、组件之间如何通讯

props(单向父传子),自定义事件(子传父),redux和context

2、JSX本质是什么?

JSX就是用React.CreateElement创造一个vnode虚拟节点,再经过diff算法,经过patch函数,对页面进行更新或者渲染

3、context是什么?如何作用?

context是一个JS的技术,应用于父组件向其所有子孙组件传递信息,常用来传递公共信息,比如主题色,语言等等,复杂一点就去用redux

4、SCU(shouldComponentUpdate)的用途

性能优化,配合不可变值使用

5、redux单向数据流

几个关键的点有view(试图),action(要用actionCreator创建),dispatch,reducer,state。

middleware是包在dispatch里

6、setState的性质

1、和并性

2、异步同步性(详见上面setState的同步和异步机制)

3、有防抖性

7、纯函数

返回一个新的值,没有其他副作用

类似如数组的slice(),concat()等等

8、生命周期组件

9、ajax应该放在哪个生命周期里

ComponentDidMount,或者useEffect

10、 列表渲染要用key

diff算法里应用到,来看是不是samenode,减少渲染次数,提高性能

11、受控组件和非受控组件

在表单中:

由React控制的输入表单元素而改变其值(state)的方式,由react.State托管称为:“受控组件”。

由ref的形式拿到数据,使用input原生state的形式管理数据的方法,

defaultValue可以设置初始值,表示为非受控组件。

(对于文件操作,只能用原生,所以会是非受控组件)

12、什么异步组件

加载大组件时使用

13、公共逻辑的解决办法

高阶组件,RenderProps

14、redux异步请求

封装异步action,在store中配置中间件redux-thunk

15、react-router懒加载

react.lazy suspense组件

//官网的示例代码
//路由之间切换的时候会有loading字符出现
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./components/Home'));
const About = lazy(() => import('./components/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);

类似的loading界面是对于没请求到的ajax,其实在hooks里可以设置一个变量,进行管理。上面有

16、pureComponent和普通component的区别

它实现了浅比较的SCU,可以优化性能

17、react事件和Dom事件的区别

react是在Dom事件之上的一层封装,react事件可以访问nativeEvent来访问该原生事件,并且这个事件是被绑定在document上统一管理的

18、react性能优化(这个问题有点广泛,下面写的是前端性能优化)

a.React:渲染列表的时候要加key,合理地使用异步组件,自定义事件要及时销毁,减少bind this的次数(使用箭头函数),合理使用pureComponent和memo(在函数式组件里,使用useCallback和useMemo),合理使用Immutable.js

b.Webpack

c.通用性能优化:图片懒加载等等

d.使用SSR

这里是对React.memo的解释

React.memo 仅检查 props 变更。如果函数组件被 React.memo 包裹,且其实现中拥有 useStateuseContext 的 Hook,当 context 发生变化时,它仍会重新渲染。

白话讲就是

当数据变化时,代码会重新执行一遍,但是子组件数据没有变化也会执行,这个时候可以使用memo将子组件封装起来,让子组件的数据只在发生改变时才会执行

针对的是子组件,并且可以自定义equal函数

而且这里有一个细节,父组件的值如果每一次都重新创建的话,其实每传过去的props,也都是新的,所以都会更新

这里是对useCallback的解释

返回一个函数,只有在依赖值变化时这个函数才会更新(与React.memo配合使用)

上述代码我们的方法使用 useCallback 包装了一层,并且后面还传入了一个 [count2] 变量,这里 useCallback 就会根据 count2 是否发生变化,从而决定是否返回一个新的函数,函数内部作用域也随之更新。

const handleClickButton2 = useCallback(() => {
  setCount2(count2 + 1);
}, [count2]);

这里是对useMemo的解释

简单来说就是传递一个创建函数和依赖项,创建函数会需要返回一个,只有在依赖项发生改变的时候,才会重新调用此函数,返回一个新的值。

useCallBack是重新创建一个函数,useMemo是一个值,

也可以把一些昂贵的计算逻辑放到 useMemo 中,只有当依赖值发生改变的时候才去更新。

const [count, setCount] = useState(0);

const userInfo = useMemo(() => {
  return {
    // ...
    name: "Jace",
    age: count
  };
}, [count]);

return <UserCard userInfo={userInfo}>

由以上可以看初useCallback针对的是函数的创建,useMemo针对的是某些特定的或者某些昂贵的计算逻辑

且useMemo的可以是一个函数,所以useMemo可以代替useCallback

而这两个和React.memo比起来又有区别,React.memo针对的是子组件的更新渲染问题

19、react和vue的共同点和区别

共同点

都支持组件化,都支持数据驱动试图,用vdom操作dom,都能满足绝大部分使用场景

区别

1、react使用jsx拥抱js进行模板代码编写,vue使用template拥抱html

2、react是函数式编程(setState),vue是声明式编程(var const)

3、react学习成本更高,需要自力更生;vue适合新手,都有现成的api等等