• react经典面试题解析


    一、类组件和函数组件的区别(面试常考)

    简单理解(所有同学都要掌握)

    1、类组件有生命周期,函数组件没有

    2、类组件需要继承 Class,函数组件不需要

    3、类组件可以获取实例化的 this,并且基于 this 做各种操作,函数组件不行

    4、类组件内部可以定义并维护 state, 函数组件都称为无状态了,那肯定不行。

    进阶理解(挑战高薪)

    函数式组件捕获了渲染时所使用的值,这是两类组件最大的不同

    创建组件LearnComponentDiff
    1. import React from "react";
    2. import FCComponent from "./fc-component";
    3. import ClassComponent from "./class-component";
    4. export default class LearnComponentDiff extends React.Component {
    5. state = {
    6. user: "王凯",
    7. };
    8. render() {
    9. return (
    10. <>
    11. <label>
    12. <b>选择一个人查看关注: </b>
    13. <select
    14. value={this.state.user}
    15. onChange={(e) => this.setState({ user: e.target.value })}
    16. >
    17. <option value="wangkai">王凯</option>
    18. <option value="zhangsan">张三</option>
    19. <option value="lisi">李四</option>
    20. </select>
    21. </label>
    22. <h1>欢迎关注 {this.state.user}!</h1>
    23. <p>
    24. <FCComponent user={this.state.user} />
    25. <b> (函数组件)</b>
    26. </p>
    27. <p>
    28. <ClassComponent user={this.state.user} />
    29. <b> (类组件)</b>
    30. </p>
    31. <p>你能看出两者的不同吗</p>
    32. </>
    33. );
    34. }
    35. }
    创建ClassComponent类组件
    1. import React from 'react';
    2. class ClassComponent extends React.Component {
    3. showMessage = () => {
    4. alert('选择的 ' + this.props.user);
    5. }
    6. handleClick = () => {
    7. setTimeout(this.showMessage, 3000);
    8. };
    9. render() {
    10. return <button onClick={this.handleClick}>尝试</button>;
    11. }
    12. }
    13. export default ClassComponent;

    点击页面后我们发现 初始化的props改变了! user 是通过 props 下发的,props不可改变,那么造成数据改变的原因就一定是 this 指向改变了。
    真正的原因也确实如此,虽然props不可改变,但是this是可变的,this.props 的每次调用都会去获取最新的 this 值,这也是React保证数据实时性的重要手段。

    那么就很清晰了,当showMessage最终执行时,此时的 this 绑定的是 张三对应的上下文,所以输出为 ‘已关注 张三’

    创建FCComponent函数组件
    1. import React from 'react';
    2. function FCComponent(props) {
    3. const showMessage = () => {
    4. alert('已关注 ' + props.user);
    5. }
    6. const handleClick = () => {
    7. setTimeout(showMessage, 3000);
    8. };
    9. return (
    10. <button onClick={handleClick}>尝试</button>
    11. );
    12. }
    13. export default FCComponent;

    最终的输出值明显为 ‘选择的 王凯’,props 会在函数执行的瞬间就被捕获,而 props 本身又是不可变值,所以我们可以确保从当前开始读取到的 props 都是最初捕获到的。当父组件传入新的 props 尝试重新渲染函数时,本质是基于新的 props 入参重新调用了一次函数,并不会影响上一次调用。这就是 Dan 所说的函数式组件捕获了渲染所使用的值,并且我们还能进一步意识到:函数组件真正将数据和渲染紧紧的绑定到一起了

    注意:

    很多人认为在函数组件中延迟输出的 state 是调用时的 state,而不是最新的 state 是一个Bug,恰恰相反,这是一个函数式组件的特性,是真正践行了React设计理念的正确方式。

    当然Hooks也给出了获取最新的props和state的方法,就是 useRef,详细用法在我们的课程已经有所介绍,同学们可以自行回顾一下

    推荐阅读

    大家可以看一下React 团队核心成员和 Redux 作者 Dan的这边文章。进阶理解这部分也借鉴了Dan大佬的这篇文章😄

    函数式组件与类组件有何不同?

    二、除jsx外,react还可以使用那些方式编写UI

    当你不想在构建环境中配置有关 JSX 编译时,不在 React 中使用 JSX 会更加方便。每个 JSX 元素只是调用 React.createElement(component, props, ...children) 的语法糖。因此,使用 JSX 可以完成的任何事情都可以通过纯 JavaScript 完成

    三、react中样式污染产生的原因

    React最终编译打包后都在一个html页面中,如果在两个组件中取一样类名分别引用在自身,那么后者会覆盖前者。默认情况下,只要导入了组件,不管组件有没有显示在页面中,组件的样式就会生效。也就是说并没有自己的局部作用域

    四、如何解决react中的样式污染

    1、手动处理 (起不同的类名,但是项目一大就会导致类名很乱,不利于团队协作)

    2、CSS IN JS : 以js的方式来处理css(推荐)

    五、什么是CSS IN JS

    CSS IN JS是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题。

    CSS IN JS 的具体实现有 50 多种,比如:React常用(CSS Modules、styled-components)、 Vue常用(