MST
星途 面试题库

面试题:Solid.js 组件生命周期复杂场景与自定义Hooks优化

假设在一个 Solid.js 应用中有一个列表组件,每个列表项是一个子组件。当子组件从列表中移除时,需要执行一些清理操作(比如取消网络请求),请描述如何利用组件生命周期函数优雅地实现此功能。另外,如果自定义一个 Hook 用于处理复杂的表单验证逻辑,在性能优化方面需要考虑哪些要点?
30.7万 热度难度
前端开发Solid.js

知识考点

AI 面试

面试题答案

一键面试

1. 列表项子组件移除时执行清理操作

在 Solid.js 中,可以使用 createEffect 结合 onCleanup 来实现类似组件生命周期中卸载时执行清理操作的功能。

假设列表子组件如下:

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

const ListItem = ({ item }) => {
  let cancelRequest;
  createEffect(() => {
    // 模拟网络请求
    const fetchData = async () => {
      // 实际请求逻辑
      cancelRequest = () => {
        // 取消请求逻辑,例如 axios 可以使用 CancelToken 来取消请求
      };
    };
    fetchData();

    onCleanup(() => {
      // 当组件从列表中移除时执行清理操作,取消网络请求
      if (cancelRequest) {
        cancelRequest();
      }
    });
  });

  return <div>{item}</div>;
};

在列表组件中使用:

import { createSignal } from'solid-js';
import ListItem from './ListItem';

const List = () => {
  const [items, setItems] = createSignal(['item1', 'item2', 'item3']);

  const removeItem = (index) => {
    const currentItems = items();
    currentItems.splice(index, 1);
    setItems(currentItems);
  };

  return (
    <div>
      {items().map((item, index) => (
        <ListItem key={index} item={item} />
      ))}
      <button onClick={() => removeItem(0)}>移除第一项</button>
    </div>
  );
};

export default List;

2. 自定义 Hook 用于表单验证逻辑的性能优化要点

  • 防抖(Debounce)和节流(Throttle):如果表单验证是基于用户输入实时触发的,使用防抖或节流来控制验证频率。例如,如果是文本输入框的验证,防抖可以避免短时间内频繁触发验证函数,减少不必要的计算。
import { createSignal, createEffect } from'solid-js';

const useDebounce = (value, delay) => {
  const [debouncedValue, setDebouncedValue] = createSignal(value);

  createEffect(() => {
    const timeout = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => clearTimeout(timeout);
  });

  return debouncedValue;
};

const useFormValidation = () => {
  const [inputValue, setInputValue] = createSignal('');
  const debouncedValue = useDebounce(inputValue, 300);

  let isValid = true;
  createEffect(() => {
    // 基于 debouncedValue 进行表单验证逻辑
    if (debouncedValue().length < 5) {
      isValid = false;
    } else {
      isValid = true;
    }
  });

  return { inputValue, setInputValue, isValid };
};
  • 避免不必要的重新渲染:在自定义 Hook 中,确保依赖项数组正确设置。例如,在 createEffect 中,如果某些值没有改变,不应该触发验证逻辑的重新执行。可以使用 createMemo 来缓存一些计算结果,避免重复计算。
  • 批量更新:如果有多个状态更新相关的验证逻辑,使用 batch 函数来批量更新,减少不必要的重新渲染。例如:
import { batch } from'solid-js';

const useFormValidation = () => {
  const [input1, setInput1] = createSignal('');
  const [input2, setInput2] = createSignal('');
  const [isValid, setIsValid] = createSignal(true);

  const validate = () => {
    batch(() => {
      let newIsValid = true;
      if (input1().length < 3) {
        newIsValid = false;
      }
      if (input2().length < 3) {
        newIsValid = false;
      }
      setIsValid(newIsValid);
    });
  };

  createEffect(() => {
    validate();
  });

  return { input1, setInput1, input2, setInput2, isValid };
};