面试题答案
一键面试- 利用
createMemo
和createEffect
:createMemo
可以创建一个响应式数据,并且只有当依赖发生变化时才会重新计算。createEffect
可以在数据变化时执行副作用操作。- 对于主题切换,我们可以将主题相关的逻辑封装在
createMemo
中,只有主题值变化时才重新计算。
- 使用
memo
包裹组件:memo
可以让Solid.js在组件的props没有变化时跳过重新渲染。- 对于与主题无关的组件,我们可以用
memo
包裹,这样在主题切换时,如果这些组件的props没有变化,就不会重新渲染。
大致代码示例:
import { createContext, createEffect, createMemo, createSignal, JSX, memo } from'solid-js';
// 创建主题上下文
const ThemeContext = createContext(null);
// 主题状态和切换函数
const [theme, setTheme] = createSignal('light');
const toggleTheme = () => setTheme(prev => prev === 'light'? 'dark' : 'light');
// 使用createMemo封装主题相关逻辑
const themeValue = createMemo(() => {
return theme() === 'light'? { color: 'black', background: 'white' } : { color: 'white', background: 'black' };
});
// 主题提供组件
const ThemeProvider: JSX.Element = ({ children }) => {
createEffect(() => {
document.body.style.color = themeValue().color;
document.body.style.backgroundColor = themeValue().background;
});
return (
<ThemeContext.Provider value={themeValue()}>
{children}
</ThemeContext.Provider>
);
};
// 与主题无关的组件,用memo包裹
const UnrelatedComponent = memo((props: { text: string }) => {
return <div>{props.text}</div>;
});
// 使用主题的组件
const ThemedComponent: JSX.Element = () => {
const theme = ThemeContext.useContext();
return <div style={{ color: theme.color, background: theme.background }}>Themed content</div>;
};
const App: JSX.Element = () => {
return (
<ThemeProvider>
<UnrelatedComponent text="This is an unrelated component" />
<ThemedComponent />
<button onClick={toggleTheme}>Toggle Theme</button>
</ThemeProvider>
);
};
export default App;
在上述代码中:
themeValue
使用createMemo
,只有theme
信号变化时才重新计算主题相关的值。UnrelatedComponent
用memo
包裹,主题切换时,只要其props
不变就不会重新渲染。ThemeProvider
中使用createEffect
在主题变化时更新document.body
的样式。