S
SolidJS3mo ago
seb

Understanding Solid Reactivity Lint Error

In the following component I get this lint warning:
The reactive variable 'handleContextMenuCommand' should be used within JSX, a tracked scope (like createEffect), or inside an event handler function, or else changes will be ignored solid/reactivity
The reactive variable 'handleContextMenuCommand' should be used within JSX, a tracked scope (like createEffect), or inside an event handler function, or else changes will be ignored solid/reactivity
But I am using it inside of an event handler function. Is this a misunderstanding on my part of how reactivity works or does the linter just not recognize that the chrome.runtime.onMessage global used by Chrome extensions can register event listeners? Here's a stripped down example of my code:
export const ExampleComponent: Component = () => {
const [isLoading, setIsLoading] = createSignal(false);

const handleContextMenuCommand = async (message: string) => {
setIsLoading(true);
await fetch('/example', { body: { message }});
setIsLoading(false);
}

// this line results in a lint error:
chrome.runtime.onMessage.addListener(handleContextMenuCommand);

onCleanup(() => {
chrome.runtime.onMessage.removeListener(handleContextMenuCommand);
});

return <div>Example</div>
};
export const ExampleComponent: Component = () => {
const [isLoading, setIsLoading] = createSignal(false);

const handleContextMenuCommand = async (message: string) => {
setIsLoading(true);
await fetch('/example', { body: { message }});
setIsLoading(false);
}

// this line results in a lint error:
chrome.runtime.onMessage.addListener(handleContextMenuCommand);

onCleanup(() => {
chrome.runtime.onMessage.removeListener(handleContextMenuCommand);
});

return <div>Example</div>
};
If this code is incorrect, what's the right way to handle it?
6 Replies
peerreynders
peerreynders3mo ago
Taking your example and reframing it for BroadcastChannel and the warning goes away. https://playground.solidjs.com/anonymous/59b7b2a2-5543-47bc-8b94-0dad942a2f46 I'd be tempted to use
// eslint-disable-next-line solid/reactivity
// eslint-disable-next-line solid/reactivity
and move on with my life. It seems the rule gives addEventListener special treatment that addListener doesn't enjoy. https://github.com/solidjs-community/eslint-plugin-solid/blob/06c60957a0135c33513fa7e567a4b15a953a127e/src/rules/reactivity.ts#L1068-L1075
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
GitHub
eslint-plugin-solid/src/rules/reactivity.ts at 06c60957a0135c33513f...
Solid-specific linting rules for ESLint. Contribute to solidjs-community/eslint-plugin-solid development by creating an account on GitHub.
seb
seb3mo ago
thank you, @peerreynders! that BroadcastChannel example was a great idea. I was wondering if maybe addEventListener was a special string that the linter looks for, but I'm also not seeing a lint error when I make this change to your code: https://playground.solidjs.com/anonymous/1ec3207d-67ef-40e6-935f-ae49d71742a7
const channel = {
addListener(eventName: string, handler: (args: any) => void) {},
removeListener(eventName: string, handler: (args: any) => void) {},
};
const channel = {
addListener(eventName: string, handler: (args: any) => void) {},
removeListener(eventName: string, handler: (args: any) => void) {},
};
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
peerreynders
peerreynders3mo ago
Just to be sure though, make a test case (with multiple changes) to see if it works as expected. I'm not sure what happens when you run a setter outside of a reactive context. I don't know if it's true anymore but some time ago derivations needed to the able to resubscribe after every change propagation and that relies on changes happening under a reactive root.
seb
seb3mo ago
found the issue! https://playground.solidjs.com/anonymous/b7b46f20-69f9-4896-82ca-89b107aadea3 so it is the case that addListener behaves differently from addEventListener. I am just not certain whether I can safely eslint-ignore this one.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
peerreynders
peerreynders3mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
seb
seb3mo ago
oh that's brilliant, I wasn't aware of from. that works!
Want results from more Discord servers?
Add your server
More Posts
Example in solid-testing-library example not workingHello, the `can render a route with the id` test in the solid-testing-library https://github.com/sol"<A> and 'use' router primitives can be only used inside a Route." When testing component in routerI receieve this error when trying to test a component. The component is inside another component thaFailed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.I have a store: ```typescript export const [mainStore, setMainStore] = createStore<StoreType>({ couSet default location stateHi, I'm trying to have a default state object for all navigation using solid router. I tried using uWhy does adding a new field duplicate the value?https://stackblitz.com/edit/github-zon5da?file=src%2FApp.tsx When entering a value in the input fiDoes SolidStart have a function like basePath of nextjs?I want to deploy SolidStart to a domain subpath. https://nextjs.org/docs/app/api-reference/next-confDependency configuration in AstroI'm trying to add `solid-bootstrap` as a dependency in an Astro + Solid project. This results in theHow do I postpone invocation of fetcher function of the solid-js resource?I have following snippet in my .tsx file. Could you please explain why mappings resource is being cahow to edit html attribute?In the v1.0rc of solidstart, the Html tag generated in the entry-server.jsx. Is there a method to chHow to deploy SolidStart project to Cloud (AWS/GCP etc.)I build a simple app with solidstart and following folders show after build the project. Following