干掉你的永远都是那些基础! 用React干爆面试官儿

292 阅读9分钟

小小总结,希望对JYM能够提供些许帮助!!!

不干爆面试官儿,就被面试官儿干爆!!!你干不干?

干掉你的永远都是那些基础,是也不是?


1.什么是 React(概念)?

  • 答案:React 是一个用于构建用户界面的 JavaScript 库,起源于 Facebook 的内部项目。它采用声明式、组件化的方式管理应用 UI,将 UI 划分为独立的可重用组件,通过组件之间的数据传递来构建动态的用户界面。

2. React 组件有哪些类型?

  • 答案:主要有函数组件和类组件两种类型。函数组件接收 props 作为参数并返回 React 元素;类组件使用 ES6 类语法,扩展自 React.Component,可以使用 this 关键字访问组件的状态和生命周期方法。

3. 什么是 JSX?

  • 答案:JSX 是 React 的语法扩展,它允许在 JavaScript 代码中写类似 HTML 的标签。JSX 最终会被 Babel 转译成 React.createElement 调用。

4. 如何创建 React 组件?

  • 答案:可以通过函数或类来创建 React 组件。函数组件直接返回 React 元素;类组件需要继承 React.Component 并在 render 方法中返回 React 元素。

示例代码

  • Greeting.jsx(函数组件):
    import React from 'react';
    
    const Greeting = ({ name }) => {
      return <h1>Hello, {name}!</h1>;
    };
    
    export default Greeting;
    
  • Welcome.jsx(类组件):
    import React, { Component } from 'react';
    
    class Welcome extends Component {
      render() {
        const { name } = this.props;
        return <h1>Welcome, {name}!</h1>;
      }
    }
    
    export default Welcome;
    
  • App.js(主组件,使用上述两个组件):
    import React from 'react';
    import Greeting from './Greeting';
    import Welcome from './Welcome';
    
    const App = () => {
      return (
        <div>
          <Greeting name="Alice" />
          <Welcome name="Bob" />
        </div>
      );
    };
    
    export default App;
    

运行React项目,会看到页面上显示了两个问候语:“Hello, Alice!”和“Welcome, Bob!”。这两个问候语分别由函数组件Greeting和类组件Welcome渲染而来。

5. React 中的 state 是什么?

  • 答案:state 是组件记忆信息的一种方式,它允许组件在数据变化时重新渲染。state 是组件私有的,并且只能通过 setState 方法来更新。

示例代码

Counter.jsx(包含计数器和按钮)

import React, { useState } from 'react';

const Counter = () =&gt; {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>计数器</h1>
      <p>当前计数: {count}</p>
      &lt;button&gt; setCount(count + 1)}&gt;增加&lt;/button&gt;
      &lt;button&gt; setCount(count - 1)}&gt;减少&lt;/button&gt;
    </div>
  );
};

export default Counter;

App.js(主组件,使用state):

import React from 'react';
import Counter from './Counter';

const App = () =&gt; {
  return (
    <div>
      <h1>React State 示例</h1>
      &lt;counter&gt;
    </div>
  );
};

export default App;

6. props 与 state 的区别是什么?

  • 答案:props 是父组件传递给子组件的数据,它是不可变的;而 state 是组件内部的数据,可以通过 setState 方法来更新。

7. 受控组件与非受控组件的区别?

  • 答案:受控组件是状态由 React 控制的组件,其值由父组件通过 props 传递,并在改变时触发回调函数;非受控组件则使用 refs 或其他方法在内部管理自己的状态。

8. React 组件的生命周期包括哪些阶段?

  • 答案:包括挂载(Mounting)、更新(Updating)、卸载(Unmounting)和错误处理(Error Handling)等阶段。

9. 常用的生命周期方法有哪些?

  • 答案:常用的有 constructor、render、componentDidMount、componentDidUpdate、componentWillUnmount 等。

10. React 16.3 之后哪些生命周期方法被标记为 UNSAFE?

  • 答案:componentWillMount、componentWillReceiveProps 和 componentWillUpdate 等生命周期方法被标记为 UNSAFE。

11. 什么是高阶组件(HOC)?

  • 答案:高阶组件是一个函数,它接收一个组件并返回一个新的组件。HOC 可以用于复用组件逻辑、修改组件 props 或 state 等。

12.React Hooks 有哪些?

  • 答案:包括 useState、useEffect、useContext、useRef、useCallback、useMemo、useReducer 等。

13. 如何使用 useState Hook?

  • 答案:useState 是一个 Hook,它返回一个状态值和一个更新它的函数。可以在函数组件中使用它来管理组件的状态。

14. 如何在 React 中进行性能优化?

  • 答案:方法包括使用 PureComponent 或 React.memo 来避免不必要的重新渲染、使用 shouldComponentUpdate 生命周期方法来控制组件的更新、使用 React 的懒加载和代码拆分等。

15. 什么是虚拟 DOM?

  • 答案:虚拟 DOM 是 React 的一个核心概念,它是一个轻量级的、表示真实 DOM 结构的对象树。当 React 组件的状态或 props 发生变化时,React 会更新虚拟 DOM,并将其与之前的虚拟 DOM 进行比较,以确定需要更新的真实 DOM 部分。

16. React 的虚拟 DOM 是如何工作的?

  • 答案:React 会先构建一棵虚拟 DOM 树,当组件状态或属性发生变化时,重新构建一棵新的虚拟 DOM 树,然后与旧的虚拟 DOM 树进行对比,找出差异的部分,最后将这些差异应用到真实的 DOM 上。

17. 为什么浏览器无法读取 JSX?

  • 答案:因为 JSX 是 JavaScript 的语法扩展,不是标准的 JavaScript 语法,浏览器无法直接识别和解析。JSX 最终会被 Babel 等工具转译成标准的 JavaScript 代码。

18. React 中的 key 有什么作用?

  • 答案:key 是 React 用于识别列表中项目的唯一标识符。在列表渲染时,通过给每个子元素添加唯一的 key,可以帮助 React 高效地更新和区分不同的子元素。

19. 如何理解 “在 React 中,一切都是组件”?

  • 答案:在 React 中,无论是简单的 HTML 标签还是复杂的页面布局,都可以被视为组件。即使是一个按钮、一个输入框等,都可以被封装成一个独立的组件,这样可以提高代码的复用性和可维护性。

20. React 中的事件处理机制是怎样的?

  • 答案:React 的事件处理机制是在 JavaScript 原生事件的基础上进行了封装。在 React 中,事件是通过合成事件的方式来处理的,合成事件保证了在不同浏览器中的一致性。同时,React 提供了一套统一的事件 API,如 onClick、onChange 等,方便开发者使用。

21.什么是 React 的严格模式(StrictMode)?

  • 答案:StrictMode 是 React 提供的一种用于帮助开发者发现潜在问题的模式。它在开发过程中会启用额外的检查和警告,例如检测到未声明的 prop、使用已废弃的 API 等,但不会导致应用崩溃。它的主要目的是为了提高代码的质量和稳定性。

22. React 中的表单处理是如何实现的?

  • 答案:React 中的表单处理通常是通过受控组件来实现的。受控组件的状态由父组件通过 props 传递和管理,用户的输入会触发相应的事件处理器(如 onChange),在这些事件处理器中,通过调用 setState 或其他状态更新方法来更新组件的状态,从而实现表单数据的控制和验证。

23. 如何进行 React 项目的部署?

  • 答案:通常可以使用一些静态站点生成器(如 Next.js)将 React 应用构建为静态站点,然后部署到服务器上;也可以使用传统的服务器渲染(SSR)或客户端渲染(CSR)的方式,将构建后的 React 应用部署到支持相应技术的服务器环境中。

24. Redux 在 React 中的作用是什么?

  • 答案:Redux 是一个用于管理应用程序状态的 JavaScript 库,它可以与 React 配合使用,实现应用状态的集中管理和预测性状态更新。通过将状态存储在一个全局的 store 中,并在各个组件之间共享,使得状态的管理更加清晰和可维护。

25. React 与 Redux 的结合方式是怎样的?

  • 答案:一般通过在 React 应用中引入 Redux 的相关库(如 react-redux),然后在需要获取或更新状态的组件中使用 connect 函数将组件连接到 Redux store。这样,组件就可以通过 props 获取到 store 中的状态,并通过 dispatch 方法来触发 action,从而更新 store 中的状态。

26. 如何在 React 中实现路由导航?

  • 答案:可以使用 React Router 库来实现路由导航。通过定义不同的路由规则和对应的组件,当 URL 发生变化时,React Router 会根据路由规则匹配到相应的组件并进行渲染,从而实现页面的跳转和内容的切换。

示例代码

  • Home.jsx(首页组件):
    import React from 'react';
    
    const Home = () => {
      return <h1>Home Page</h1>;
    };
    
    export default Home;
    
  • About.jsx(关于页面组件):
    import React from 'react';
    
    const About = () => {
      return <h1>About Page</h1>;
    };
    
    export default About;
    
  • Contact.jsx(联系页面组件):
    import React from 'react';
    
    const Contact = () => {
      return <h1>Contact Page</h1>;
    };
    
    export default Contact;
    
  • App.js(主组件,设置路由):
    import React from 'react';
    import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
    import Home from './Home';
    import About from './About';
    import Contact from './Contact';
    
    const App = () => {
      return (
        <Router>
          <div>
            <nav>
              <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/about">About</Link></li>
                <li><Link to="/contact">Contact</Link></li>
              </ul>
            </nav>
            <Switch>
              <Route exact path="/" component={Home} />
              <Route path="/about" component={About} />
              <Route path="/contact" component={Contact} />
            </Switch>
          </div>
        </Router>
      );
    };
    
    export default App;
    

运行React项目,会看到一个导航栏,包含“Home”、“About”和“Contact”三个链接。当你点击这些链接时,页面会相应地切换到不同的内容,而无需重新加载整个页面。

27. React 中的 lazy loading(懒加载)是如何实现的?

  • 答案:可以使用 React.lazy 和 Suspense 来实现懒加载。React.lazy 用于动态导入组件,只有在需要渲染该组件时才会去加载;Suspense 则用于在组件加载完成之前显示一些加载指示信息。

  • 示例代码

  • HeavyComponent.jsx(懒加载的组件):

    import React from 'react';
    
    const HeavyComponent = () => {
      return (
        <div>
          <h1>重组件加载了!</h1>
          <p>我是一个很大的组件,只有在需要的时候才会被加载。</p>
        </div>
      );
    };
    
    export default HeavyComponent;
    
  • App.js(主组件,使用懒加载和Suspense):

    import React, { Suspense, lazy } from 'react';
    
    const HeavyComponent = lazy(() => import('./HeavyComponent'));
    
    const App = () => {
      const [isVisible, setIsVisible] = React.useState(false);
    
      return (
        <div>
          <h1>React 懒加载示例</h1>
          <button onClick={() => setIsVisible(true)}>加载重组件</button>
    
          {isVisible && (
            <Suspense fallback={<div>加载中...</div>}>
              <HeavyComponent />
            </Suspense>
          )}
        </div>
      );
    };
    
    export default App;
    

运行你的React项目,你会看到一个按钮。当点击“加载重组件”按钮时,HeavyComponent会被懒加载,并在加载完成后显示其内容。

28. React 中的代码分割(code splitting)是如何实现的?

  • 答案:通常借助 Webpack 等构建工具来实现代码分割。通过配置 Webpack,可以将代码拆分成多个较小的 chunk,然后根据需要异步加载这些 chunk,减少初始加载时的代码量。

29. React 中的 context 有什么用?如何使用?

  • 答案:Context 用于在组件树中传递数据,特别是在多层嵌套的组件结构中,可以避免逐层传递 props。使用 createContext 创建一个上下文对象,然后在提供者组件(Provider)中使用 value 属性传递数据,在消费者组件(Consumer)中通过 useContext 钩子获取数据。

30. React 中的 refs 是什么?如何使用?

  • 答案:refs 是 React 提供的一种方式,用于直接访问 DOM 元素或组件实例。可以通过创建 ref 对象(如 useRef、createRef 等),并将其附加到需要访问的元素或组件上,然后在需要的地方通过 ref.current 来获取对它们的引用。

示例代码

  • InputComponent.jsx(包含输入框和按钮):
    import React from 'react';
    
    const InputComponent = ({ inputRef }) => {
      return (
        <div>
          <input ref={inputRef} type="text" placeholder="请输入内容" />
          <button onClick={() => alert(inputRef.current.value)}>显示输入内容</button>
        </div>
      );
    };
    
    export default InputComponent;
    
  • App.js(主组件,使用refs):
    import React, { createRef } from 'react';
    import InputComponent from './InputComponent';
    
    const App = () => {
      const inputRef = createRef();
    
      return (
        <div>
          <h1>React Refs 示例</h1>
          <InputComponent inputRef={inputRef} />
        </div>
      );
    };
    
    export default App;