Qwik JS中如何传递函数作为Props?问题及解决方案咨询
Qwik JS 组件间状态交互解决方案
核心问题解答
能否直接传递普通函数作为props?
不能。Qwik的序列化机制要求组件props必须是可序列化的类型(原始值、对象字面量、QRL等),普通函数无法被序列化,这就是你遇到Only primitive and object literals can be serialized报错的原因。子组件能否访问父组件的store?
可以,但需要遵循Qwik的响应式规则,不能直接跨组件引用未序列化的状态或函数。
理想解决方案
针对你用Header的store控制Modal显示的场景,推荐以下三种可行方案:
方案1:直接传递store引用作为props
这是最简单直接的方式,useStore创建的状态容器是可序列化的,子组件可以直接修改store的属性触发响应式更新。
Header父组件
import { component$, useStore } from '@builder.io/qwik'; import Modal from './Modal'; export default component$(() => { const store = useStore({ modal: false }); return ( <header> <button onClick$={() => (store.modal = true)}>打开弹窗</button> <Modal store={store} /> </header> ); });
Modal子组件
import { component$ } from '@builder.io/qwik'; interface ModalProps { store: { modal: boolean }; } export default component$<ModalProps>(({ store }) => { return ( store.modal && ( <div class="modal"> <button onClick$={() => (store.modal = false)}>关闭弹窗</button> </div> ) ); });
方案2:用$包装回调函数转为QRL传递
Qwik的$函数可以将普通函数转换为QRL(Qwik可引用函数),QRL是可序列化的函数引用,能够安全作为props传递。
Header父组件
import { component$, useStore, $ } from '@builder.io/qwik'; import Modal from './Modal'; export default component$(() => { const store = useStore({ modal: false }); // 用$包装回调,转为可序列化的QRL const onClose = $(() => { store.modal = false; }); return ( <header> <button onClick$={() => (store.modal = true)}>打开弹窗</button> <Modal isOpen={store.modal} onClose={onClose} /> </header> ); });
Modal子组件
import { component$ } from '@builder.io/qwik'; interface ModalProps { isOpen: boolean; onClose: () => void; } export default component$<ModalProps>(({ isOpen, onClose }) => { return ( isOpen && ( <div class="modal"> <button onClick$={onClose}>关闭弹窗</button> </div> ) ); });
方案3:使用上下文(Context)共享状态
如果组件层级较深,或需要在多个组件间共享弹窗状态,使用上下文是更优雅的方案。
创建上下文文件 modal-context.ts
import { createContextId, useContextProvider, useContext } from '@builder.io/qwik'; export const ModalContext = createContextId<{ modal: boolean; closeModal: () => void; }>('modal-context'); export const useModalContext = () => useContext(ModalContext);
Header父组件
import { component$, useStore, $ } from '@builder.io/qwik'; import { ModalContext } from './modal-context'; import Modal from './Modal'; export default component$(() => { const store = useStore({ modal: false }); const closeModal = $(() => { store.modal = false; }); // 向上下文注入状态和操作方法 useContextProvider(ModalContext, { modal: store.modal, closeModal, }); return ( <header> <button onClick$={() => (store.modal = true)}>打开弹窗</button> <Modal /> </header> ); });
Modal子组件
import { component$ } from '@builder.io/qwik'; import { useModalContext } from './modal-context'; export default component$(() => { const { modal, closeModal } = useModalContext(); return ( modal && ( <div class="modal"> <button onClick$={closeModal}>关闭弹窗</button> </div> ) ); });
内容的提问来源于stack exchange,提问作者Muhtasim Fuad Showmik
相关产品推荐
相关产品推荐

