File tree Expand file tree Collapse file tree 7 files changed +136
-1
lines changed
apps/website/content/docs/rules
packages/plugins/eslint-plugin-react-dom/src Expand file tree Collapse file tree 7 files changed +136
-1
lines changed Original file line number Diff line number Diff line change 58
58
" dom-no-dangerously-set-innerhtml" ,
59
59
" dom-no-dangerously-set-innerhtml-with-children" ,
60
60
" dom-no-find-dom-node" ,
61
+ " dom-no-flush-sync" ,
61
62
" dom-no-missing-button-type" ,
62
63
" dom-no-missing-iframe-sandbox" ,
63
64
" dom-no-namespace" ,
Original file line number Diff line number Diff line change @@ -79,6 +79,7 @@ full: true
79
79
| [ ` no-dangerously-set-innerhtml-with-children ` ] ( ./dom-no-dangerously-set-innerhtml-with-children ) | 2️⃣ | ` 🔍 ` | Prevents DOM elements using ` dangerouslySetInnerHTML ` and ` children ` at the same time. |
80
80
| [ ` no-dangerously-set-innerhtml ` ] ( ./dom-no-dangerously-set-innerhtml ) | 1️⃣ | ` 🔍 ` | Prevents DOM elements using ` dangerouslySetInnerHTML ` . |
81
81
| [ ` no-find-dom-node ` ] ( ./dom-no-find-dom-node ) | 2️⃣ | ` 🔍 ` | Prevents using ` findDOMNode ` . |
82
+ | [ ` no-flush-sync ` ] ( ./dom-no-flush-sync ) | 1️⃣ | ` 🔍 ` | Prevents using ` flushSync ` . |
82
83
| [ ` no-missing-button-type ` ] ( ./dom-no-missing-button-type ) | 1️⃣ | ` 🔍 ` | Enforces explicit ` type ` attribute for ` button ` elements. |
83
84
| [ ` no-missing-iframe-sandbox ` ] ( ./dom-no-missing-iframe-sandbox ) | 1️⃣ | ` 🔍 ` | Enforces explicit ` sandbox ` attribute for ` iframe ` elements. |
84
85
| [ ` no-namespace ` ] ( ./dom-no-namespace ) | 2️⃣ | ` 🔍 ` | Enforces the absence of a ` namespace ` in React elements. |
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import { name, version } from "../package.json";
2
2
import noDangerouslySetInnerHTML from "./rules/no-dangerously-set-innerhtml" ;
3
3
import noDangerouslySetInnerHTMLWithChildren from "./rules/no-dangerously-set-innerhtml-with-children" ;
4
4
import noFindDomNode from "./rules/no-find-dom-node" ;
5
+ import noFlushSync from "./rules/no-flush-sync" ;
5
6
import noMissingButtonType from "./rules/no-missing-button-type" ;
6
7
import noMissingIframeSandbox from "./rules/no-missing-iframe-sandbox" ;
7
8
import noNamespace from "./rules/no-namespace" ;
@@ -21,6 +22,7 @@ export const plugin = {
21
22
"no-dangerously-set-innerhtml" : noDangerouslySetInnerHTML ,
22
23
"no-dangerously-set-innerhtml-with-children" : noDangerouslySetInnerHTMLWithChildren ,
23
24
"no-find-dom-node" : noFindDomNode ,
25
+ "no-flush-sync" : noFlushSync ,
24
26
"no-missing-button-type" : noMissingButtonType ,
25
27
"no-missing-iframe-sandbox" : noMissingIframeSandbox ,
26
28
"no-namespace" : noNamespace ,
Original file line number Diff line number Diff line change @@ -80,4 +80,4 @@ class AutoSelectingInput extends Component {
80
80
81
81
## Further Reading
82
82
83
- - [ React: APIs findDOMNode] ( https://react.dev/reference/react-dom/findDOMNode )
83
+ - [ React DOM : APIs findDOMNode] ( https://react.dev/reference/react-dom/findDOMNode )
Original file line number Diff line number Diff line change
1
+ ---
2
+ title : no-flush-sync
3
+ ---
4
+
5
+ ** Full Name in ` eslint-plugin-react-dom ` **
6
+
7
+ ``` plain copy
8
+ react-dom/no-flush-sync
9
+ ```
10
+
11
+ ** Full Name in ` @eslint-react/eslint-plugin ` **
12
+
13
+ ``` plain copy
14
+ @eslint-react/dom/no-flush-sync
15
+ ```
16
+
17
+ ** Features**
18
+
19
+ ` 🔍 `
20
+
21
+ ## What it does
22
+
23
+ This rule reports usages of ` flushSync ` .
24
+
25
+ ` flushSync ` can significantly hurt performance, and may unexpectedly force pending Suspense boundaries to show their fallback state.
26
+
27
+ Most of the time, ` flushSync ` can be avoided, so use ` flushSync ` as a last resort.
28
+
29
+ ## Examples
30
+
31
+ ### Failing
32
+
33
+ ``` tsx
34
+ import { flushSync } from " react-dom" ;
35
+
36
+ flushSync (() => {
37
+ setSomething (123 );
38
+ });
39
+ ```
40
+
41
+ ## Implementation
42
+
43
+ - [ Rule source] ( https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom/src/rules/no-flush-sync.ts )
44
+ - [ Test source] ( https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom/src/rules/no-flush-sync.spec.ts )
45
+
46
+ ## Further Reading
47
+
48
+ - [ React DOM: APIs flushSync] ( https://react.dev/reference/react-dom/flushSync )
Original file line number Diff line number Diff line change
1
+ import { allValid , ruleTester } from "../../../../../test" ;
2
+ import rule , { RULE_NAME } from "./no-flush-sync" ;
3
+
4
+ ruleTester . run ( RULE_NAME , rule , {
5
+ invalid : [
6
+ {
7
+ code : /* tsx */ `
8
+ import { flushSync } from 'react-dom';
9
+
10
+ flushSync(() => {
11
+ setSomething(123);
12
+ });
13
+ ` ,
14
+ errors : [
15
+ { messageId : "noFlushSync" } ,
16
+ ] ,
17
+ } ,
18
+ {
19
+ code : /* tsx */ `
20
+ import reactDom from 'react-dom';
21
+
22
+ reactDom.flushSync(() => {
23
+ setSomething(123);
24
+ });
25
+ ` ,
26
+ errors : [
27
+ { messageId : "noFlushSync" } ,
28
+ ] ,
29
+ } ,
30
+ ] ,
31
+ valid : [
32
+ ...allValid ,
33
+ ] ,
34
+ } ) ;
Original file line number Diff line number Diff line change
1
+ import type { RuleFeature } from "@eslint-react/shared" ;
2
+ import { AST_NODE_TYPES as T } from "@typescript-eslint/types" ;
3
+ import type { CamelCase } from "string-ts" ;
4
+
5
+ import { createRule } from "../utils" ;
6
+
7
+ export const RULE_NAME = "no-flush-sync" ;
8
+
9
+ export const RULE_FEATURES = [
10
+ "CHK" ,
11
+ ] as const satisfies RuleFeature [ ] ;
12
+
13
+ export type MessageID = CamelCase < typeof RULE_NAME > ;
14
+
15
+ export default createRule < [ ] , MessageID > ( {
16
+ meta : {
17
+ type : "problem" ,
18
+ docs : {
19
+ description : "warns against using `flushSync`" ,
20
+ [ Symbol . for ( "rule_features" ) ] : RULE_FEATURES ,
21
+ } ,
22
+ messages : {
23
+ noFlushSync : "Using 'flushSync' is uncommon and can hurt the performance of your app." ,
24
+ } ,
25
+ schema : [ ] ,
26
+ } ,
27
+ name : RULE_NAME ,
28
+ create ( context ) {
29
+ if ( ! context . sourceCode . text . includes ( "flushSync" ) ) return { } ;
30
+ return {
31
+ CallExpression ( node ) {
32
+ const { callee } = node ;
33
+ switch ( callee . type ) {
34
+ case T . Identifier :
35
+ if ( callee . name === "flushSync" ) {
36
+ context . report ( { messageId : "noFlushSync" , node } ) ;
37
+ }
38
+ return ;
39
+ case T . MemberExpression :
40
+ if ( callee . property . type === T . Identifier && callee . property . name === "flushSync" ) {
41
+ context . report ( { messageId : "noFlushSync" , node } ) ;
42
+ }
43
+ return ;
44
+ }
45
+ } ,
46
+ } ;
47
+ } ,
48
+ defaultOptions : [ ] ,
49
+ } ) ;
You can’t perform that action at this time.
0 commit comments