面试题答案
一键面试1. 理解 useStore
和 useSignal
useStore
:用于创建一个可观察的存储对象,多个组件可以订阅该存储对象的变化。在SSR或SSG场景下,它有助于在不同组件间共享状态。useSignal
:创建一个响应式信号,当信号值变化时,依赖它的组件会重新渲染。它更侧重于局部状态管理。
2. 实现方案
- SSR模式下的状态持久化:
- 在服务器端渲染时,初始化状态并将其序列化到HTML中。客户端在挂载时,从HTML中提取状态并恢复。
- 使用
useStore
存储全局状态,在服务器端渲染时填充初始值,客户端挂载时复用该值。
- SSG模式下的状态持久化:
- 在生成静态页面时,计算并注入初始状态。同样,客户端挂载时恢复该状态。
- 利用
useSignal
处理页面内局部状态,确保在静态生成和客户端交互时状态一致。
3. 代码示例
假设我们有一个简单的计数器应用。
初始化Qwik项目
首先,创建一个Qwik项目:
npm create qwik@latest my - project
cd my - project
定义 useStore
状态
在 src/store/counterStore.ts
文件中:
import { useStore } from '@builder.io/qwik';
export const useCounterStore = () => {
const store = useStore({
count: 0
});
const increment = () => {
store.count++;
};
const decrement = () => {
if (store.count > 0) {
store.count--;
}
};
return {
store,
increment,
decrement
};
};
使用 useStore
和 useSignal
在组件中
在 src/routes/index.tsx
文件中:
import { component$, useSignal } from '@builder.io/qwik';
import { useCounterStore } from '../store/counterStore';
export default component$(() => {
const { store, increment, decrement } = useCounterStore();
const localSignal = useSignal(0);
const incrementLocal = () => {
localSignal.value++;
};
return (
<div>
<h1>Global Counter: {store.count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<h2>Local Signal Counter: {localSignal.value}</h2>
<button onClick={incrementLocal}>Increment Local</button>
</div>
);
});
4. 确保状态一致性和稳定性
- SSR/SSG初始化:在服务器端渲染(SSR)或静态站点生成(SSG)阶段,确保状态正确初始化。例如,在SSR中,可能从数据库或其他数据源获取初始状态,在SSG中,提前计算好初始状态。
- 客户端挂载:在客户端挂载时,避免重复初始化状态,而是从已有的序列化状态中恢复。
- 状态更新逻辑:确保无论是在服务器端渲染还是客户端交互过程中,状态更新逻辑是一致的。例如,
increment
和decrement
函数的逻辑在不同渲染模式下应该相同。
通过上述方案和代码示例,可以在结合SSR或SSG的Qwik项目中,巧妙利用 useStore
和 useSignal
实现高效的状态持久化,并确保不同渲染模式下状态的一致性和稳定性。