Skip to content

Commit

Permalink
fix(lint): don't trigger useJsxKeyInIterable when iterating on non-…
Browse files Browse the repository at this point in the history
…jsx things
  • Loading branch information
dyc3 committed May 1, 2024
1 parent 47662b3 commit d524940
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ fn handle_collections(
let node = AnyJsExpression::cast(node.into_syntax())?;
handle_potential_react_component(node, model, is_inside_jsx)
})
.flatten()
.collect()
}

Expand Down Expand Up @@ -198,6 +199,7 @@ fn handle_iterators(
let returned_value = statement.argument()?;
handle_potential_react_component(returned_value, model, is_inside_jsx)
})
.flatten()
.collect::<Vec<_>>();

Some(res)
Expand All @@ -207,7 +209,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
Expand All @@ -218,6 +219,7 @@ fn handle_iterators(
let returned_value = statement.argument()?;
handle_potential_react_component(returned_value, model, is_inside_jsx)
})
.flatten()
.collect::<Vec<_>>();
Some(res)
}
Expand All @@ -231,19 +233,41 @@ fn handle_potential_react_component(
node: AnyJsExpression,
model: &SemanticModel,
is_inside_jsx: bool,
) -> Option<UseJsxKeyInIterableState> {
) -> Option<Vec<UseJsxKeyInIterableState>> {
let node = unwrap_parenthesis(node)?;

if is_inside_jsx {
match node {
AnyJsExpression::JsBinaryExpression(_) => {
return None;
}
AnyJsExpression::JsConditionalExpression(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::<Vec<_>>();

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()))
Some(vec![UseJsxKeyInIterableState::CantDetermineJSXProp(
node.range(),
)])
}
} else {
let range =
handle_react_component(ReactComponentExpression::cast_ref(node.syntax())?, model)?;
Some(UseJsxKeyInIterableState::MissingKeyProps(range))
Some(vec![UseJsxKeyInIterableState::MissingKeyProps(range)])
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,14 +542,33 @@ invalid.jsx:33:19 lint/correctness/useJsxKeyInIterable ━━━━━━━━
```

```
invalid.jsx:33:24 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid.jsx:33:29 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! Missing key property for this element in iterable.
31 │ (<h1>{[<h1></h1>, <h1></h1>, <h1></h1>]}</h1>)
32 │
> 33 │ (<h1>{[<h1></h1>, xyz, abc? <h2></h2>: bcd]}</h1>)
│ ^^^^
34 │
35 │ (<h1>{data.map(c => <h1></h1>)}</h1>)
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.
```

```
invalid.jsx:33:40 lint/correctness/useJsxKeyInIterable ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! Cannot determine whether this child has the required key prop.
31 │ (<h1>{[<h1></h1>, <h1></h1>, <h1></h1>]}</h1>)
32 │
> 33 │ (<h1>{[<h1></h1>, xyz, abc? <h2></h2>: bcd]}</h1>)
^^^^^^^^^^^^^^^^^^^
^^^
34 │
35 │ (<h1>{data.map(c => <h1></h1>)}</h1>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@ React.Children.map(c => React.cloneElement(c, {key: c}));

(<h1>{data.map(c => (<h1 key={c}></h1>))}</h1>)

(<h1>{data.map(c => {return (<h1 key={c}></h1>)})}</h1>)
(<h1>{data.map(c => {return (<h1 key={c}></h1>)})}</h1>)

<>{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)}</>
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ React.Children.map(c => React.cloneElement(c, {key: c}));
(<h1>{data.map(c => (<h1 key={c}></h1>))}</h1>)

(<h1>{data.map(c => {return (<h1 key={c}></h1>)})}</h1>)

<>{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)}</>

```

0 comments on commit d524940

Please sign in to comment.