solid
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSolidJS Core Knowledge
SolidJS 核心知识
Full Reference: See advanced.md for WebSocket primitive, context provider, chat component, room management, Socket.IO integration, and store patterns.
Deep Knowledge: Usewith technology:mcp__documentation__fetch_docsfor comprehensive documentation.solid
完整参考:有关WebSocket原语、上下文提供器、聊天组件、房间管理、Socket.IO集成和store模式的内容,请查看advanced.md。
深度知识获取:使用工具,指定technology为mcp__documentation__fetch_docs以获取完整文档。solid
When NOT to Use This Skill
何时不使用此技能
Skip this skill when:
- Working with React (use - APIs are different)
frontend-react - Building Vue applications (use )
vue-composition - Using Svelte (use )
svelte - Working with Angular (use )
angular - Need server-side only logic (no framework needed)
在以下场景跳过此技能:
- 处理React相关内容时(请使用- 两者API不同)
frontend-react - 构建Vue应用时(请使用)
vue-composition - 使用Svelte时(请使用)
svelte - 处理Angular相关内容时(请使用)
angular - 仅需要服务器端逻辑时(无需框架)
Component Structure
组件结构
tsx
import { createSignal, createEffect, createMemo } from 'solid-js';
interface Props {
name: string;
count?: number;
}
function Counter(props: Props) {
const [localState, setLocalState] = createSignal('');
const doubled = createMemo(() => (props.count ?? 0) * 2);
createEffect(() => {
console.log('Count changed:', props.count);
});
return (
<div>
<h1>Hello {props.name}</h1>
<p>Doubled: {doubled()}</p>
<button onClick={() => setLocalState('clicked')}>
Click
</button>
</div>
);
}tsx
import { createSignal, createEffect, createMemo } from 'solid-js';
interface Props {
name: string;
count?: number;
}
function Counter(props: Props) {
const [localState, setLocalState] = createSignal('');
const doubled = createMemo(() => (props.count ?? 0) * 2);
createEffect(() => {
console.log('Count changed:', props.count);
});
return (
<div>
<h1>Hello {props.name}</h1>
<p>Doubled: {doubled()}</p>
<button onClick={() => setLocalState('clicked')}>
Click
</button>
</div>
);
}Reactivity Primitives
响应式原语
| API | Purpose |
|---|---|
| Reactive state |
| Cached computation |
| Side effects |
| Async data fetching |
| Nested reactive objects |
| API | 用途 |
|---|---|
| 响应式状态 |
| 缓存计算结果 |
| 副作用处理 |
| 异步数据获取 |
| 嵌套响应式对象 |
Key Differences from React
与React的主要区别
- No Virtual DOM - fine-grained updates
- Props are getters - access via
props.name - No dependency arrays - auto-tracking
- Components run once - not on every render
- JSX compiles differently - expressions are reactive
- 无虚拟DOM - 细粒度更新
- Props是getter - 通过访问
props.name - 无需依赖数组 - 自动跟踪依赖
- 组件仅运行一次 - 并非每次渲染都运行
- JSX编译方式不同 - 表达式具备响应式
Control Flow
控制流
tsx
import { Show, For, Switch, Match } from 'solid-js';
<Show when={isLoggedIn()} fallback={<Login />}>
<Dashboard />
</Show>
<For each={items()}>{(item) => <Item data={item} />}</For>tsx
import { Show, For, Switch, Match } from 'solid-js';
<Show when={isLoggedIn()} fallback={<Login />}>
<Dashboard />
</Show>
<For each={items()}>{(item) => <Item data={item} />}</For>Anti-Patterns
反模式
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| Destructuring props | Loses reactivity | Access via |
| Using React patterns | Different paradigm | Use Solid primitives |
Not using | Manual conditional logic | Use |
| Recreating signals in components | Components run once | Create outside or use stores |
Using | XSS vulnerability | Use DOMPurify |
Not cleaning up in | Memory leaks | Add cleanup logic |
| 反模式 | 问题原因 | 正确做法 |
|---|---|---|
| 解构props | 丢失响应式特性 | 通过 |
| 使用React模式 | 范式不同 | 使用Solid原语 |
不使用 | 手动编写条件逻辑 | 使用 |
| 在组件内重复创建signals | 组件仅运行一次 | 在组件外创建或使用stores |
未经清理就使用 | XSS漏洞 | 使用DOMPurify |
未在 | 内存泄漏 | 添加清理逻辑 |
Quick Troubleshooting
快速故障排查
| Issue | Likely Cause | Solution |
|---|---|---|
| Props not reactive | Destructured props | Access via |
| Signal not updating | Forgot to call setter | Use |
| Effect not running | Not tracking signal | Call signal inside effect: |
| Component re-running | Treating like React | Components run once, use signals |
| List not updating | Using array methods | Use |
| Memory leaks | No cleanup | Use |
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| Props无响应式 | 已解构props | 通过 |
| Signal未更新 | 忘记调用setter | 使用 |
| Effect未触发 | 未跟踪signal | 在effect内调用signal: |
| 组件重复运行 | 按React方式处理 | 组件仅运行一次,使用signals管理状态 |
| 列表未更新 | 使用普通数组方法 | 使用 |
| 内存泄漏 | 未清理资源 | 使用 |
Production Readiness
生产就绪指南
Error Handling
错误处理
tsx
import { ErrorBoundary } from 'solid-js';
function App() {
return (
<ErrorBoundary
fallback={(err, reset) => (
<div>
<p>Error: {err.message}</p>
<button onClick={reset}>Retry</button>
</div>
)}
>
<MainContent />
</ErrorBoundary>
);
}tsx
import { ErrorBoundary } from 'solid-js';
function App() {
return (
<ErrorBoundary
fallback={(err, reset) => (
<div>
<p>Error: {err.message}</p>
<button onClick={reset}>Retry</button>
</div>
)}
>
<MainContent />
</ErrorBoundary>
);
}Performance
性能优化
tsx
// Lazy loading components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
);
}
// Batch updates (rarely needed)
import { batch } from 'solid-js';
batch(() => {
setCount(count() + 1);
setName('New Name');
});tsx
// Lazy loading components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
);
}
// Batch updates (rarely needed)
import { batch } from 'solid-js';
batch(() => {
setCount(count() + 1);
setName('New Name');
});Store Patterns
Store模式
tsx
import { createStore, produce } from 'solid-js/store';
const [state, setState] = createStore({
users: [] as User[],
filters: { active: true },
});
// Immutable-style updates with produce
function addUser(user: User) {
setState(produce((s) => {
s.users.push(user);
}));
}
// Path-based updates
setState('users', (users) => [...users, newUser]);
setState('filters', 'active', false);tsx
import { createStore, produce } from 'solid-js/store';
const [state, setState] = createStore({
users: [] as User[],
filters: { active: true },
});
// Immutable-style updates with produce
function addUser(user: User) {
setState(produce((s) => {
s.users.push(user);
}));
}
// Path-based updates
setState('users', (users) => [...users, newUser]);
setState('filters', 'active', false);Testing
测试
tsx
import { render, screen } from '@solidjs/testing-library';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';
describe('Counter', () => {
it('increments on click', async () => {
const user = userEvent.setup();
render(() => <Counter initial={0} />);
const button = screen.getByRole('button');
await user.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
});tsx
import { render, screen } from '@solidjs/testing-library';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';
describe('Counter', () => {
it('increments on click', async () => {
const user = userEvent.setup();
render(() => <Counter initial={0} />);
const button = screen.getByRole('button');
await user.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
});Security
安全
tsx
// innerHTML - only with trusted content
<div innerHTML={sanitizedHtml} />
// Prefer text content
<div>{userInput}</div> // Safe - auto-escaped
// XSS prevention
import DOMPurify from 'dompurify';
function SafeHtml(props: { html: string }) {
const clean = () => DOMPurify.sanitize(props.html);
return <div innerHTML={clean()} />;
}tsx
// innerHTML - only with trusted content
<div innerHTML={sanitizedHtml} />
// Prefer text content
<div>{userInput}</div> // Safe - auto-escaped
// XSS prevention
import DOMPurify from 'dompurify';
function SafeHtml(props: { html: string }) {
const clean = () => DOMPurify.sanitize(props.html);
return <div innerHTML={clean()} />;
}Monitoring Metrics
监控指标
| Metric | Target |
|---|---|
| Bundle size | < 30KB |
| First Contentful Paint | < 1s |
| Time to Interactive | < 1.5s |
| Memory usage | Stable |
| 指标 | 目标值 |
|---|---|
| 包体积 | < 30KB |
| 首次内容绘制 | < 1秒 |
| 可交互时间 | < 1.5秒 |
| 内存占用 | 稳定 |
Checklist
检查清单
- ErrorBoundary for error handling
- Suspense for async operations
- Lazy loading for code splitting
- createStore for complex state
- Virtual lists for large data
- No innerHTML with user input
- Testing with @solidjs/testing-library
- SSR with SolidStart
- Fine-grained updates (no unnecessary re-renders)
- Bundle analysis
- 使用ErrorBoundary处理错误
- 对异步操作使用Suspense
- 懒加载组件以拆分代码
- 使用createStore管理复杂状态
- 对大数据使用虚拟列表
- 不使用innerHTML处理用户输入
- 使用@solidjs/testing-library进行测试
- 使用SolidStart实现SSR
- 细粒度更新(无不必要的重渲染)
- 包体积分析
Reference Documentation
参考文档
Deep Knowledge: Usewith technology:mcp__documentation__fetch_docsfor comprehensive documentation.solid
- Primitives Cheatsheet
- React Migration Guide
深度知识获取:使用工具,指定technology为mcp__documentation__fetch_docs以获取完整文档。solid
- 原语速查表
- React迁移指南