面试题答案
一键面试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 };
};