agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
69 lines (60 loc) • 2.15 kB
JavaScript
/**
* @file Detect key prop issues
* @description Single responsibility: Identify React key prop problems in lists
*/
const { iterateLines } = require('../../utils/patternDetector');
/**
* Detect key prop issues
*/
function detectKeyPropIssues(lines, filePath) {
const issues = [];
iterateLines(lines, (line, lineNumber, trimmed, i) => {
// Array index as key
if (/key=\s*{\s*(?:index|i|idx)\s*}/.test(trimmed)) {
issues.push({
type: 'index_as_key',
severity: 'MEDIUM',
category: 'React',
location: `${filePath}:${lineNumber}`,
line: lineNumber,
code: trimmed,
description: 'Using array index as key can cause issues with component state',
summary: 'Array index used as React key',
recommendation: 'Use stable, unique IDs as keys instead of array indices',
effort: 1,
impact: 'Prevents state issues in dynamic lists',
estimatedSavings: 'Prevents hard-to-debug state bugs'
});
}
// Missing key in map
if (/\.map\s*\(/.test(trimmed)) {
// Check next few lines for JSX without key
let hasJSX = false;
let hasKey = false;
for (let j = i; j < Math.min(i + 10, lines.length); j++) {
const checkLine = lines[j];
if (/<\w+/.test(checkLine)) hasJSX = true;
if (/key=/.test(checkLine)) hasKey = true;
if (/\)\s*[;,]/.test(checkLine)) break;
}
if (hasJSX && !hasKey) {
issues.push({
type: 'missing_key_in_list',
severity: 'HIGH',
category: 'React',
location: `${filePath}:${lineNumber}`,
line: lineNumber,
code: trimmed,
description: 'List items without key prop cause React reconciliation issues',
summary: 'Missing key prop in list',
recommendation: 'Add unique key prop to list items',
effort: 1,
impact: 'Improves React reconciliation performance',
estimatedSavings: '20-40% list update performance'
});
}
}
});
return issues;
}
module.exports = detectKeyPropIssues;