Skip to content

Commit f5efaff

Browse files
authored
Merge pull request #49 from solidjs-community/fix/component-event-listeners
Allow forwarding event handlers without wrapper function in Components
2 parents 4c2d3af + b08fff8 commit f5efaff

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

docs/reactivity.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ function Component() {
448448
return <div on:click={() => console.log(signal())} />;
449449
}
450450

451+
const Parent = (props) => {
452+
return <Child onClick={props.onClick} />;
453+
};
454+
451455
const Component = (props) => {
452456
const [signal] = createSignal();
453457
return (

src/rules/reactivity.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ const rule: TSESLint.RuleModule<MessageIds, []> = {
238238
untrackedReactive:
239239
"The reactive variable '{{name}}' should be used within JSX, a tracked scope (like createEffect), or inside an event handler function.",
240240
expectedFunctionGotExpression:
241-
"The reactive variable '{{name}}' should be wrapped in a function for reactivity. This includes event handler bindings, which are not reactive like other JSX props.",
241+
"The reactive variable '{{name}}' should be wrapped in a function for reactivity. This includes event handler bindings on native elements, which are not reactive like other JSX props.",
242242
badSignal:
243243
"The reactive variable '{{name}}' should be called as a function when used in {{where}}.",
244244
badUnnamedDerivedSignal:
@@ -755,7 +755,10 @@ const rule: TSESLint.RuleModule<MessageIds, []> = {
755755
if (node.type === "JSXExpressionContainer") {
756756
if (
757757
node.parent?.type === "JSXAttribute" &&
758-
/^on[:A-Z]/.test(sourceCode.getText(node.parent.name))
758+
/^on[:A-Z]/.test(sourceCode.getText(node.parent.name)) &&
759+
node.parent.parent?.type === "JSXOpeningElement" &&
760+
node.parent.parent.name.type === "JSXIdentifier" &&
761+
isDOMElementName(node.parent.parent.name.name)
759762
) {
760763
// Expect a function if the attribute is like onClick={} or on:click={}. From the docs:
761764
// Events are never rebound and the bindings are not reactive, as it is expensive to

test/rules/reactivity.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ export const cases = run("reactivity", rule, {
165165
const [signal, setSignal] = createSignal(1);
166166
return <div on:click={() => console.log(signal())} />;
167167
}`,
168+
// event listeners are reactive on components
169+
`const Parent = props => {
170+
return <Child onClick={props.onClick} />;
171+
}`,
168172
// Pass reactive variables as-is into provider value prop
169173
`const Component = props => {
170174
const [signal] = createSignal();
@@ -554,7 +558,7 @@ export const cases = run("reactivity", rule, {
554558
},
555559
],
556560
},
557-
// event listeners not rebound
561+
// event listeners are not rebound on native elements
558562
{
559563
code: `
560564
const Component = props => {

0 commit comments

Comments
 (0)