面试题答案
一键面试1. 避免不必要重新渲染的原理
Svelte 的响应式系统会追踪变量的变化,当变量变化时,依赖该变量的部分会重新渲染。在使用 Context API 时,为了避免不必要的重新渲染,应尽量减少上下文数据的粒度,只更新真正需要变化的部分,并且确保只有依赖变化数据的组件重新渲染。
2. 优化方法
- 细粒度数据传递:不要在上下文中传递大的对象或数组,而是拆分成单个属性。这样如果某个属性变化,不会导致依赖整个对象或数组的组件不必要的重新渲染。
- 使用
$:
语法控制响应式:通过$:
语法来定义响应式变量,精确控制哪些部分对数据变化做出响应。
3. 代码示例
假设我们有一个父组件 App.svelte
,一个中间组件 Middle.svelte
和一个子组件 Child.svelte
,通过 Context API 进行通信。
App.svelte
<script>
import Middle from './Middle.svelte';
import { setContext } from 'svelte';
let count = 0;
let name = 'John';
// 使用细粒度数据传递
setContext('countContext', {
count,
increment: () => {
count++;
}
});
setContext('nameContext', {
name,
changeName: (newName) => {
name = newName;
}
});
</script>
<button on:click={() => count++}>Increment count</button>
<button on:click={() => name = 'Jane'}>Change name</button>
<Middle />
Middle.svelte
<script>
import Child from './Child.svelte';
</script>
<Child />
Child.svelte
<script>
import { getContext } from'svelte';
const countContext = getContext('countContext');
const nameContext = getContext('nameContext');
let localCount;
let localName;
// 使用 $: 语法精确控制响应式
$: localCount = countContext.count;
$: localName = nameContext.name;
</script>
<p>Count: {localCount}</p>
<p>Name: {localName}</p>
在这个示例中,App.svelte
通过 Context API 传递了细粒度的数据 count
和 name
及其更新函数。Child.svelte
使用 $:
语法来创建本地响应式变量 localCount
和 localName
,这样只有当 count
或 name
变化时,相关部分才会重新渲染,避免了不必要的重新渲染。