【React】精选5题

1. React Hooks 在使用上有哪些限制?

  1. 只能在函数组件内部使用:React Hooks 只能在函数组件内部使用,不能在类组件中使用。这是因为 React Hooks 是基于函数式编程的思想,通过函数来管理组件的状态和生命周期。

  2. 只能在顶层调用:React Hooks 必须在函数组件的顶层调用,不能在条件语句、循环语句或嵌套函数中调用。这是为了保证 Hooks 的执行顺序和稳定性,以及避免对状态的错误管理。

  3. Hook 名称必须以 “use” 开头:自定义的 Hook 名称必须以 “use” 开头,这是为了标识该函数是一个 Hook,并能够在其它 Hook 内使用。

  4. 必须按顺序调用:React Hooks 必须按照相同的顺序调用,且每次函数组件渲染时的调用顺序必须相同。这是为了确保在组件重新渲染时,React 能够正确地将之前的状态和效果与当前的状态和效果进行匹配。

  5. 不能在循环中使用 Hook:React Hooks 不能在循环中使用,因为循环中的闭包函数会共享相同的状态。如果需要在循环中使用 Hook,可以使用自定义 Hook 来解决这个问题。

需要注意的是,这些限制都是为了保证 React Hooks 的正确性和稳定性,遵守这些限制可以更好地使用和理解 React Hooks。

2. useEffect 与 useLayoutEffect 有什么区别?

useEffect 和 useLayoutEffect 是 React Hooks 中用于处理副作用的两个钩子函数,它们之间的主要区别在于触发的时机不同。

useEffect 会在组件渲染完成后异步执行副作用代码。它不会阻塞组件的渲染,会在浏览器绘制完成后才执行。这意味着 useEffect 中的副作用代码可能会在页面重新渲染之后才执行,因此它适合处理不需要立即执行的副作用,如数据请求、事件绑定等。

useLayoutEffect 会在组件渲染完成后同步执行副作用代码。它会在浏览器绘制之前执行,即在页面重新渲染之前执行。这意味着 useLayoutEffect 中的副作用代码会在页面重新渲染之前执行,可能会阻塞组件的渲染,因此需要注意使用 useLayoutEffect 的性能影响。它适合处理需要在页面重新渲染之前立即执行的副作用,如获取 DOM 元素的尺寸、触发动画等。

总结来说,useEffect 是一种异步执行副作用代码的钩子函数,适合处理不需要立即执行的副作用;useLayoutEffect 是一种同步执行副作用代码的钩子函数,适合处理需要在页面重新渲染之前立即执行的副作用。根据具体的需求,选择合适的钩子函数来处理副作用,可以优化和控制组件的行为。

3. React 中怎么实现状态自动保存(KeepAlive)?

什么是状态保存?

假设有下述场景:

移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目,点击查看其详情,进入详情页,从详情页退回列表页时,需要停留在离开列表页时的浏览位置上

类似的数据或场景还有已填写但未提交的表单、管理系统中可切换和可关闭的功能标签等,这类数据随着用户交互逐渐变化或增长,这里理解为状态,在交互过程中,因为某些原因需要临时离开交互场景,则需要对状态进行保存

在 React 中,我们通常会使用路由去管理不同的页面,而在切换页面时,路由将会卸载掉未匹配的页面组件,所以上述列表页例子中,当用户从详情页退回列表页时,会回到列表页顶部,因为列表页组件被路由卸载后重建了,状态被丢失。

在 React 中,可以通过使用组件的状态和生命周期方法来实现状态自动保存(KeepAlive)的功能。下面是一种实现方式:

  1. 创建一个高阶组件(Higher-Order Component,HOC)来包装需要进行状态自动保存的组件。这个高阶组件的作用是在组件销毁时将组件的状态保存下来,并在组件重新Mount时将之前保存的状态恢复。
import React, { Component } from 'react';

const withKeepAlive = WrappedComponent => {
  return class extends Component {
    constructor(props) {
      super(props);
      this.state = {
        savedState: null
      };
    }

    componentDidMount() {
      if (this.state.savedState) {
        this.setState({ savedState: null });
      }
    }

    componentWillUnmount() {
      this.setState({ savedState: this.props });
    }

    render() {
      const { savedState } = this.state;
      if (savedState) {
        return <WrappedComponent {...savedState} />;
      }
      return <WrappedComponent {...this.props} />;
    }
  };
};
  1. 在需要进行状态自动保存的组件上使用这个高阶组件进行包装。
import React from 'react';

const MyComponent = ({ count, setCount }) => {
  // ...组件的实现
};

export default withKeepAlive(MyComponent);

这样,当这个被包装的组件被销毁时,其状态会被保存下来。当组件重新 Mount 时,之前保存的状态会被恢复,实现了状态的自动保存。

需要注意的是,这只是一种简单的实现方式,如果需要更复杂的 KeepAlive 功能,可以考虑使用 React 的 Context 或 Redux 等状态管理工具来实现。

4. mobx 和 redux 有什么区别?

MobX 和 Redux 都是用于状态管理的库,它们之间有以下区别:

  1. 哲学不同:MobX 倾向于提供简单和直观的 API,使得状态管理变得更加简单和自然。它使用可观察对象和自动追踪的方式来管理状态,通过对状态的直接修改来触发自动更新。而 Redux 则更倾向于函数式编程的思想,通过纯函数的方式对状态进行更新,通过触发 action 来派发更新。

  2. 数据流管理方式不同:在 MobX 中,状态的变化是自动的,当状态被观察的时候,任何对状态的修改都会被自动追踪并触发相关的更新。这种方式下,状态的更新是一种直接的、隐式的方式。而 Redux 中,状态的更新是显式的,通过派发 action 来改变状态,再通过 reducer 函数来返回新的状态。

  3. API 复杂度不同:由于 MobX 的设计理念是提供简单和直观的 API,因此使用 MobX 可以更快地上手并进行状态管理。而 Redux 的设计更加严格,需要编写额外的 action 和 reducer 函数,因此在一些复杂的应用中,会需要更多的代码和配置。

  4. 性能差异:由于 MobX 使用了自动追踪的方式来管理状态,它可以做到更细粒度的更新,只更新相关的组件,因此在某些场景下,MobX 的性能可能会比 Redux 更好。但是,在一些需要更严格控制状态更新的场景下,Redux 可能更适合。

综上所述,MobX 更加面向简单和直观的状态管理,适用于快速开发和小型应用;而 Redux 更加严格和可控,适用于大型应用和需要严格控制状态更新的场景。根据具体的需求,选择合适的状态管理库可以提高开发效率和应用性能。

5. 下面函数组件的输出分别是什么?

下面是一个简单的函数组件,有两个按钮:“alert”、“add”。

如果先点击“alert”按钮,再点击一次“add”按钮,那么弹窗框中的值和页面中展示value分别是什么?

const FunctionComponent = () => {
  const [value, setValue] = useState(1)

  const log = () => {
    setTimeout(() => {
      alert(value)
    }, 3000);
  }

  return (
    <div>
      <p>FunctionComponent</p>
      <div>value: {value}</div>
      <button onClick={log}>alert</button>
      <button onClick={() => setValue(value + 1)}>add</button>
    </div>
  )
}

答:
展示的value是2,alert的值是1

你可能感兴趣的:(react.js,javascript,前端)