MST

星途 面试题库

面试题:Solid.js中createEffect在异步操作里如何处理数据变化

假设你在Solid.js项目中使用`createEffect`进行一个异步API调用获取用户信息,当用户信息发生变化时(例如通过其他函数更新了本地存储的用户ID从而触发新的API调用),`createEffect`应该如何正确地处理这种数据变化,避免重复请求或出现数据不一致问题?请写出大致的代码结构并解释。
31.3万 热度难度
前端开发Solid.js

知识考点

AI 面试

面试题答案

一键面试

代码结构

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

// 创建信号存储用户信息和用户ID
const [userInfo, setUserInfo] = createSignal(null);
const [userId, setUserId] = createSignal(null);

createEffect(() => {
    // 获取当前用户ID
    const currentUserId = userId();

    // 如果用户ID存在,则进行API调用
    if (currentUserId) {
        const controller = new AbortController();
        const { signal } = controller;

        fetch(`/api/user/${currentUserId}`, { signal })
          .then(response => response.json())
          .then(data => {
                // 只有在当前用户ID未发生变化时才更新用户信息
                if (userId() === currentUserId) {
                    setUserInfo(data);
                }
            })
          .catch(error => {
                if (error.name!== 'AbortError') {
                    console.error('Error fetching user info:', error);
                }
            });

        // 返回清理函数,在组件卸载或依赖变化时取消请求
        return () => controller.abort();
    }
});

// 模拟更新用户ID的函数
const updateUserId = newId => {
    setUserId(newId);
};

解释

  1. 信号创建
    • 使用createSignal创建了userInfouserId两个信号。userInfo用于存储获取到的用户信息,初始值为nulluserId用于存储用户ID,初始值也为null
  2. createEffect
    • createEffect会在其依赖的信号(这里是userId)发生变化时自动运行。
    • 首先获取当前的userId,如果userId存在,则发起异步API调用。
    • 使用AbortController来控制请求,在createEffect重新运行(例如userId变化)或组件卸载时,通过调用controller.abort()取消未完成的请求,避免重复请求。
    • 在API调用成功后,检查当前的userId是否与发起请求时的userId一致,只有一致时才更新userInfo,这样可以避免因userId在请求过程中变化而导致的数据不一致问题。
  3. 更新函数
    • updateUserId函数用于模拟更新userId,当userId更新时,createEffect会重新运行,触发新的API调用获取最新的用户信息。