Skip to content

Commit dee960b

Browse files
authored
refactor(plugins/x): rename 'ensure-forward-ref-using-ref' to 'no-useless-forward-ref' (#987)
1 parent 5a95379 commit dee960b

20 files changed

+225
-122
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# ADR 0000: Choice between "useless" and "unnecessary" in rule naming
2+
3+
## Status
4+
5+
Accepted
6+
7+
## Context
8+
9+
When naming rules related to identifying redundant or non-functional code (e.g., in linting or static analysis), the terms "useless" and "unnecessary" both convey a sense of superfluity. However, their nuanced semantic differences could lead to ambiguity if misapplied. For example, a `forwardRef`-wrapped component that is never passed a `ref` is entirely without purpose, but other scenarios might involve optional code that is only redundant in specific contexts. A consistent naming convention is needed to ensure clarity and accuracy in rule documentation and error messaging.
10+
11+
## Decision
12+
13+
Use "useless" to describe code that has no functional purpose under any circumstances (e.g., a `forwardRef` with no `ref` usage).
14+
Use "unnecessary" to describe code that is contextually redundant but not strictly non-functional (e.g., an `useEffect` that runs event-specific logic).
15+
16+
## Consequences
17+
18+
- Improved clarity: Developers can better discern whether code is strictly non-functional ("useless") or situationally redundant ("unnecessary").
19+
20+
- Consistency: Rules and error messages will align with precise semantic definitions.
21+
22+
- Potential learning curve: Teams may need documentation to understand the distinction initially.
23+
24+
## Alternatives Considered
25+
26+
1. Using only "unnecessary" for all cases:
27+
- Rejected because it conflates fundamentally distinct scenarios (strictly non-functional vs. contextually redundant), reducing diagnostic precision.
28+
29+
2. Using only "useless" for all cases:
30+
- Rejected because it could mislabel code that is optional but valid in other contexts, leading to confusion or dismissal of valid feedback.
31+
32+
## Related ADRs
33+
34+
N/A
35+
36+
## Links
37+
38+
N/A
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# ADR 0001: Rename ensure-forward-ref-using-ref to no-useless-forward-ref
2+
3+
## Status
4+
5+
Accepted
6+
7+
## Context
8+
9+
The rule `ensure-forward-ref-using-ref` detects React `forwardRef`-wrapped components that never receive a `ref` prop. This matches the "useless" criteria defined in ADR 0000, as such components serve no functional purpose. The current name lacks alignment with our established `no-<category>-<term>` naming convention and semantic categorization.
10+
11+
## Decision
12+
13+
Rename the rule to **`no-useless-forward-ref`** to:
14+
15+
1. Adhere to the `no-<category>-<term>` pattern used in similar rules (e.g., `no-useless-state`).
16+
2. Reflect the strict "useless" classification per ADR 0000, since unreferenced `forwardRef` components are functionally inert.
17+
18+
## Consequences
19+
20+
- **Consistency**: Aligns with existing rule taxonomy and terminology.
21+
- **Clarity**: Clearly signals the rule's focus on non-functional code.
22+
- **Documentation updates**: Requires migration guides and rule metadata changes.
23+
24+
## Alternatives Considered
25+
26+
Using `no-unnecessary-forward-ref`:
27+
28+
- Rejected because "unnecessary" implies optional redundancy, whereas unreferenced `forwardRef` has zero runtime utility.
29+
30+
## Related ADRs
31+
32+
- [ADR 0000: Choice between "useless" and "unnecessary" in rule naming](./0000-choice-between-useless-and-unnecessary-in-rule-naming.md)
33+
34+
## Links
35+
36+
N/A

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"editor.defaultFormatter": "dprint.dprint"
44
},
55
"[jsonc]": {
6-
"editor.defaultFormatter": "dprint.dprint"
6+
"editor.defaultFormatter": "vscode.json-language-features"
77
},
88
"[typescript]": {
99
"editor.defaultFormatter": "dprint.dprint"

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## v1.33.0 (Draft)
2+
3+
### 🪄 Improvements
4+
5+
- refactor(plugins/x): rename `ensure-forward-ref-using-ref` to `no-useless-forward-ref`
6+
7+
### 📝 Changes you should be aware of
8+
9+
The following rules have been renamed:
10+
111
## v1.32.1 (2025-03-13)
212

313
### 🐞 Fixes

apps/website/content/docs/changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
title: Changelog
33
---
44

5+
## v1.33.0 (Draft)
6+
7+
### 🪄 Improvements
8+
9+
- refactor(plugins/x): rename `ensure-forward-ref-using-ref` to `no-useless-forward-ref`
10+
11+
### 📝 Changes you should be aware of
12+
13+
The following rules have been renamed:
14+
515
## v1.32.1 (2025-03-13)
616

717
### 🐞 Fixes

apps/website/content/docs/deprecated.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ full: true
88

99
| Rule | Replaced by | Deprecated in |
1010
| :--------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :------------ |
11-
| [`jsx-uses-vars`](/docs/rules/jsx-uses-vars) | [`use-jsx-vars`](/docs/rules/use-jsx-vars) | 1.22.0 |
1211
| [`jsx-no-duplicate-props`](/docs/rules/jsx-no-duplicate-props) | [`no-duplicate-jsx-props`](/docs/rules/no-duplicate-jsx-props) | 1.22.0 |
13-
| [`no-complicated-conditional-rendering`](/docs/rules/no-complicated-conditional-rendering) | [`no-complex-conditional-rendering`](/docs/rules/no-complex-conditional-rendering) | 1.6.0 |
14-
| [`no-children-in-void-dom-elements`](/docs/rules/dom-no-children-in-void-dom-elements) | [`no-void-elements-with-children`](/docs/rules/dom-no-void-elements-with-children) | 1.22.0 |
15-
| [`no-redundant-custom-hook`](/docs/rules/hooks-extra-no-useless-custom-hooks) | [`no-useless-custom-hooks`](/docs/rules/hooks-extra-no-useless-custom-hooks) | 1.21.0 |
12+
| [`jsx-uses-vars`](/docs/rules/jsx-uses-vars) | [`use-jsx-vars`](/docs/rules/use-jsx-vars) | 1.22.0 |
1613
| [`ensure-custom-hooks-using-other-hooks`](/docs/rules/hooks-extra-no-useless-custom-hooks) | [`no-useless-custom-hooks`](/docs/rules/hooks-extra-no-useless-custom-hooks) | 1.13.0 |
17-
| [`ensure-use-memo-has-non-empty-deps`](/docs/rules/hooks-extra-ensure-use-memo-has-non-empty-deps) | [`no-unnecessary-use-memo`](/docs/rules/hooks-extra-no-unnecessary-use-memo) | 1.13.0 |
14+
| [`ensure-forward-ref-using-ref`](/docs/rules/ensure-forward-ref-using-ref) | [`no-useless-forward-ref`](/docs/rules/no-useless-forward-ref) | 1.33.0 |
1815
| [`ensure-use-callback-has-non-empty-deps`](/docs/rules/hooks-extra-ensure-use-callback-has-non-empty-deps) | [`no-unnecessary-use-callback`](/docs/rules/hooks-extra-no-unnecessary-use-callback) | 1.13.0 |
16+
| [`ensure-use-memo-has-non-empty-deps`](/docs/rules/hooks-extra-ensure-use-memo-has-non-empty-deps) | [`no-unnecessary-use-memo`](/docs/rules/hooks-extra-no-unnecessary-use-memo) | 1.13.0 |
17+
| [`no-children-in-void-dom-elements`](/docs/rules/dom-no-children-in-void-dom-elements) | [`no-void-elements-with-children`](/docs/rules/dom-no-void-elements-with-children) | 1.22.0 |
18+
| [`no-complicated-conditional-rendering`](/docs/rules/no-complicated-conditional-rendering) | [`no-complex-conditional-rendering`](/docs/rules/no-complex-conditional-rendering) | 1.6.0 |
19+
| [`no-redundant-custom-hook`](/docs/rules/hooks-extra-no-useless-custom-hooks) | [`no-useless-custom-hooks`](/docs/rules/hooks-extra-no-useless-custom-hooks) | 1.21.0 |
1920

2021
## Presets
2122

apps/website/content/docs/roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ title: Roadmap
3232

3333
### Add suggestion-fix feature to rules that can be fixed interactively
3434

35-
- [ ] `ensure-forward-ref-using-ref`
35+
- [ ] `no-useless-forward-ref`
3636
- [ ] `no-leaked-conditional-rendering`
3737
- [ ] `no-redundant-should-component-update`
3838
- [ ] `no-unused-class-component-members`

apps/website/content/docs/rules/meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"---Core Rules---",
55
"avoid-shorthand-boolean",
66
"avoid-shorthand-fragment",
7-
"ensure-forward-ref-using-ref",
7+
"no-useless-forward-ref",
88
"no-access-state-in-setstate",
99
"no-array-index-key",
1010
"no-children-count",

apps/website/content/docs/rules/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ full: true
2020
| :----------------------------------------------------------------------------------- | :- | :------------ | :---------------------------------------------------------------------------------------------------- | :------: |
2121
| [`avoid-shorthand-boolean`](./avoid-shorthand-boolean) | 0️⃣ | `🔍` `🔧` | Enforces the use of explicit boolean values for boolean attributes. | |
2222
| [`avoid-shorthand-fragment`](./avoid-shorthand-fragment) | 0️⃣ | `🔍` | Enforces the use of explicit `<Fragment>` components instead of the shorthand `<>` or `</>` syntax. | |
23-
| [`ensure-forward-ref-using-ref`](./ensure-forward-ref-using-ref) | 1️⃣ | `🔍` | Requires that components wrapped with `forwardRef` must have a `ref` parameter. | |
23+
| [`no-useless-forward-ref`](./no-useless-forward-ref) | 1️⃣ | `🔍` | Requires that components wrapped with `forwardRef` must have a `ref` parameter. | |
2424
| [`no-access-state-in-setstate`](./no-access-state-in-setstate) | 2️⃣ | `🔍` | Prevents accessing `this.state` inside `setState` calls. | |
2525
| [`no-array-index-key`](./no-array-index-key) | 1️⃣ | `🔍` | Prevents using an item's index in the array as its key | |
2626
| [`no-children-count`](./no-children-count) | 1️⃣ | `🔍` | Prevents using `Children.count`. | |

apps/website/next.config.mjs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ const config = {
8989
destination: "/docs/rules/no-complex-conditional-rendering",
9090
permanent: true,
9191
},
92+
{
93+
source: "/docs/rules/ensure-forward-ref-using-ref",
94+
destination: "/docs/rules/no-useless-forward-ref",
95+
permanent: true,
96+
},
9297
{
9398
source: "/docs/rules/dom-no-children-in-void-dom-elements",
9499
destination: "/docs/rules/dom-no-void-elements-with-children",
@@ -114,11 +119,6 @@ const config = {
114119
destination: "/docs/rules/hooks-extra-no-useless-custom-hooks",
115120
permanent: true,
116121
},
117-
{
118-
source: "/docs/rules/debug-react-hooks",
119-
destination: "/docs/rules/debug-hook",
120-
permanent: true,
121-
},
122122
];
123123
},
124124
};

0 commit comments

Comments
 (0)