S
SolidJS8mo 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
peerreynders8mo 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
sebOP8mo 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
peerreynders8mo 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
sebOP8mo 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
peerreynders8mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
seb
sebOP8mo ago
oh that's brilliant, I wasn't aware of from. that works!
Want results from more Discord servers?
Add your server