MST
星途 面试题库

面试题:Solid.js 组件在更新过程中异步操作的状态管理

当 Solid.js 组件接收到新的 props 并触发更新时,其中存在正在进行的异步操作(比如一个未完成的 API 调用)。如何确保在组件更新时,这些异步操作能够正确处理,避免数据冲突或旧数据覆盖新数据的情况?请详细阐述处理思路并给出相关代码片段。
30.6万 热度难度
前端开发Solid.js

知识考点

AI 面试

面试题答案

一键面试

处理思路

  1. 使用状态管理来跟踪异步操作状态:在组件内部使用响应式状态来记录异步操作是否正在进行,以及操作的结果。
  2. 取消旧的异步操作:当新的 props 到来触发更新时,如果有正在进行的异步操作,应该尝试取消它。对于 fetch API 调用,可以使用 AbortController 来实现取消操作。
  3. 确保数据一致性:在更新数据时,要根据当前的异步操作状态和新的 props 来决定如何更新 UI,避免旧数据覆盖新数据。

代码示例

import { createSignal, onCleanup } from 'solid-js';

const MyComponent = ({ newProp }) => {
  const [data, setData] = createSignal(null);
  const [isLoading, setIsLoading] = createSignal(false);
  let controller;

  const fetchData = async () => {
    controller = new AbortController();
    const signal = controller.signal;
    setIsLoading(true);
    try {
      const response = await fetch(`your-api-url?param=${newProp}`, { signal });
      const result = await response.json();
      setData(result);
    } catch (error) {
      if (error.name === 'AbortError') {
        // 操作被取消,不做处理
      } else {
        console.error('Error fetching data:', error);
      }
    } finally {
      setIsLoading(false);
    }
  };

  // 每次新的props到来重新发起请求
  if (newProp) {
    // 取消上一次未完成的请求
    if (controller) {
      controller.abort();
    }
    fetchData();
  }

  onCleanup(() => {
    // 组件卸载时取消未完成的请求
    if (controller) {
      controller.abort();
    }
  });

  return (
    <div>
      {isLoading() && <p>Loading...</p>}
      {data() && <p>{JSON.stringify(data())}</p>}
    </div>
  );
};

export default MyComponent;

在上述代码中:

  1. createSignal 用于创建响应式状态 dataisLoading,分别用于存储异步操作的结果和表示操作是否正在进行。
  2. fetchData 函数用于发起异步请求,并使用 AbortController 来控制请求的取消。
  3. newProp 变化时,先检查是否有正在进行的请求,如果有则取消,然后发起新的请求。
  4. onCleanup 函数用于在组件卸载时取消未完成的请求,避免内存泄漏。