You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SolidJS中传递只读Props?依赖注入场景lint问题求解

关于SolidJS中只读Props注入单例服务的Lint警告问题

问题描述

我经常给Solid组件传递用于单例服务依赖注入的只读属性,简化示例如下,但SolidJS的lint规则抛出错误:

The reactive variable 'props.firestore' should be used within JSX, a tracked scope (like createEffect), or inside an event handler function.

这类只读Props的使用看似合理,我是否误用了SolidJS的Props?或是ESLint规则不够完善?我不想盲目禁用lint警告,希望确认正确做法。

示例代码

export const DocumentView = (props: { firestore: Firestore }) => {
  const query = query(collection(props.firestore), "my-collection");
  const [docs, setDocs] = createSignal([]);
  const unsubscribeQuery = onSnapshot(query, (snapshot) => {
    setDocs(() => snapshot);
  });
  onCleanup(() => unsubscribeQuery());
  return (
    <div>
      <For each={docs}>{(i) => <p>{i}</p>}</For>{" "}
    </div>
  );
};

正确做法解析

你并没有误用SolidJS的Props,这个Lint警告是因为Solid的ESLint规则对响应式变量的追踪场景做了严格校验,但你的场景属于「非响应式的单例依赖注入」,规则没识别到这种特殊情况。

解决这个问题不需要禁用警告,有两种更规范的处理方式:

1. 明确标记Props为非响应式(推荐)

因为你传递的是单例服务(比如Firestore实例),它本身不会是响应式值,你可以在解构Props时添加/* @once */注释,告诉ESLint这个Props只需要读取一次,不需要追踪:

export const DocumentView = ({ firestore /* @once */ }: { firestore: Firestore }) => {
  const query = query(collection(firestore), "my-collection");
  const [docs, setDocs] = createSignal([]);
  const unsubscribeQuery = onSnapshot(query, (snapshot) => {
    setDocs(() => snapshot);
  });
  onCleanup(() => unsubscribeQuery());
  return (
    <div>
      <For each={docs}>{(i) => <p>{i}</p>}</For>{" "}
    </div>
  );
};

2. 将初始化逻辑放入createEffect(适合未来可能变为响应式的场景)

如果未来这个Props有可能变成响应式(比如切换不同的Firestore实例),可以把查询初始化逻辑放到createEffect里,这样既符合Lint规则,又能自动响应Props变化并清理旧订阅:

export const DocumentView = (props: { firestore: Firestore }) => {
  const [docs, setDocs] = createSignal([]);

  createEffect(() => {
    const query = query(collection(props.firestore), "my-collection");
    const unsubscribe = onSnapshot(query, (snapshot) => {
      setDocs(() => snapshot);
    });
    // 自动清理当前订阅
    return unsubscribe;
  });

  return (
    <div>
      <For each={docs}>{(i) => <p>{i}</p>}</For>{" "}
    </div>
  );
};

警告触发原因

Solid的Props本身是响应式的,ESLint规则会检查所有props的读取场景,如果读取不在JSX、追踪作用域(createEffect/createMemo等)或事件处理器里,就会默认认为你可能遗漏了响应式追踪。但你的场景是单例注入,不需要追踪变化,所以用/* @once */注释是最直接的适配方案。

内容的提问来源于stack exchange,提问作者JustinM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:41:29