diff --git a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs
index 9704bfa506e4..bb659ce45eeb 100644
--- a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs
+++ b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs
@@ -55,7 +55,6 @@ declare_node_union! {
#[derive(Debug)]
pub enum UseJsxKeyInIterableState {
MissingKeyProps(TextRange),
- CantDetermineJSXProp(TextRange),
}
impl Rule for UseJsxKeyInIterable {
@@ -93,21 +92,6 @@ impl Rule for UseJsxKeyInIterable {
});
Some(diagnostic)
}
- UseJsxKeyInIterableState::CantDetermineJSXProp(state) => {
- let diagnostic = RuleDiagnostic::new(
- rule_category!(),
- state,
- markup! {
- "Cannot determine whether this child has the required ""key"" prop."
- },
- )
- .note(markup! {
- "Either return a JSX expression, or suppress this instance if you determine it is safe."
- }).note(markup! {
- "Check the ""React documentation for why a key prop is required"". "
- });
- Some(diagnostic)
- }
}
}
}
@@ -133,6 +117,7 @@ fn handle_collections(
let node = AnyJsExpression::cast(node.into_syntax())?;
handle_potential_react_component(node, model, is_inside_jsx)
})
+ .flatten()
.collect()
}
@@ -198,6 +183,7 @@ fn handle_iterators(
let returned_value = statement.argument()?;
handle_potential_react_component(returned_value, model, is_inside_jsx)
})
+ .flatten()
.collect::>();
Some(res)
@@ -207,7 +193,6 @@ fn handle_iterators(
match body {
AnyJsFunctionBody::AnyJsExpression(expr) => {
handle_potential_react_component(expr, model, is_inside_jsx)
- .map(|state| vec![state])
}
AnyJsFunctionBody::JsFunctionBody(body) => {
let res = body
@@ -218,6 +203,7 @@ fn handle_iterators(
let returned_value = statement.argument()?;
handle_potential_react_component(returned_value, model, is_inside_jsx)
})
+ .flatten()
.collect::>();
Some(res)
}
@@ -231,19 +217,33 @@ fn handle_potential_react_component(
node: AnyJsExpression,
model: &SemanticModel,
is_inside_jsx: bool,
-) -> Option {
+) -> Option> {
let node = unwrap_parenthesis(node)?;
+
if is_inside_jsx {
+ if let AnyJsExpression::JsConditionalExpression(node) = node {
+ let results = [node.consequent().ok()?, node.alternate().ok()?]
+ .into_iter()
+ .filter_map(|node| handle_potential_react_component(node, model, is_inside_jsx))
+ .flatten()
+ .collect::>();
+
+ return if !results.is_empty() {
+ Some(results)
+ } else {
+ None
+ };
+ }
if let Some(node) = ReactComponentExpression::cast_ref(node.syntax()) {
let range = handle_react_component(node, model)?;
- Some(UseJsxKeyInIterableState::MissingKeyProps(range))
+ Some(vec![UseJsxKeyInIterableState::MissingKeyProps(range)])
} else {
- Some(UseJsxKeyInIterableState::CantDetermineJSXProp(node.range()))
+ None
}
} else {
let range =
handle_react_component(ReactComponentExpression::cast_ref(node.syntax())?, model)?;
- Some(UseJsxKeyInIterableState::MissingKeyProps(range))
+ Some(vec![UseJsxKeyInIterableState::MissingKeyProps(range)])
}
}
diff --git a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx.snap b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx.snap
index 03ae8d055aee..a5e6779e092d 100644
--- a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx.snap
+++ b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx.snap
@@ -523,39 +523,20 @@ invalid.jsx:33:8 lint/correctness/useJsxKeyInIterable ━━━━━━━━
```
```
-invalid.jsx:33:19 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+invalid.jsx:33:29 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- ! Cannot determine whether this child has the required key prop.
-
- 31 │ ({[, , ]}
)
- 32 │
- > 33 │ ({[, xyz, abc? : bcd]}
)
- │ ^^^
- 34 │
- 35 │ ({data.map(c => )}
)
-
- i Either return a JSX expression, or suppress this instance if you determine it is safe.
-
- i Check the React documentation for why a key prop is required.
-
-
-```
-
-```
-invalid.jsx:33:24 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
- ! Cannot determine whether this child has the required key prop.
+ ! Missing key property for this element in iterable.
31 │ ({[, , ]}
)
32 │
> 33 │ ({[, xyz, abc? : bcd]}
)
- │ ^^^^^^^^^^^^^^^^^^^
+ │ ^^^^
34 │
35 │ ({data.map(c => )}
)
- i Either return a JSX expression, or suppress this instance if you determine it is safe.
+ i The order of the items may change, and having a key can help React identify which item was moved.
- i Check the React documentation for why a key prop is required.
+ i Check the React documentation.
```
@@ -577,25 +558,6 @@ invalid.jsx:35:21 lint/correctness/useJsxKeyInIterable ━━━━━━━━
i Check the React documentation.
-```
-
-```
-invalid.jsx:37:21 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
- ! Cannot determine whether this child has the required key prop.
-
- 35 │ ({data.map(c => )}
)
- 36 │
- > 37 │ ({data.map(c => xyz)}
)
- │ ^^^
- 38 │
- 39 │ ({data.map(c => ())}
)
-
- i Either return a JSX expression, or suppress this instance if you determine it is safe.
-
- i Check the React documentation for why a key prop is required.
-
-
```
```
diff --git a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx
index 21c82252ba7e..c9e7be44af33 100644
--- a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx
+++ b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx
@@ -45,4 +45,10 @@ React.Children.map(c => React.cloneElement(c, {key: c}));
({data.map(c => ())}
)
-({data.map(c => {return ()})}
)
\ No newline at end of file
+({data.map(c => {return ()})}
)
+
+<>{data.reduce((total, next) => total + next, 0)}>
+
+<>{data.reduce((a, b) => Math.max(a, b), 0)}>
+
+<>{data.reduce((a, b) => a > b ? a : b, 0)}>
diff --git a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap
index f2611fff4426..d52efbcdd157 100644
--- a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap
+++ b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap
@@ -52,4 +52,11 @@ React.Children.map(c => React.cloneElement(c, {key: c}));
({data.map(c => ())}
)
({data.map(c => {return ()})}
)
+
+<>{data.reduce((total, next) => total + next, 0)}>
+
+<>{data.reduce((a, b) => Math.max(a, b), 0)}>
+
+<>{data.reduce((a, b) => a > b ? a : b, 0)}>
+
```