BUG: bad usage of React hooks and Regex
Concerned file: src/components/markdown.tsx
What ?
I spotted multiple bad usages of React Hooks (spotted with SonarQube)
Where ?
- Line 114: const ref = useRef<HTMLDivElement>(null)
- Line 115: const viewRef = useRef<EditorView | null>(null)
- Line 116: const [blockStarted, setBlockStarted] = useState(false)
- Line 117: the useEffect()
Why ?
React Hooks are called conditionally. React Hooks must be called in the exact same order in every component render. In this case we got early return above line 104:
return <> </>
From React documentation:
Always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls. React is relying on the order of the Hook calls to know which local state matches which Hook call. That is why it’s important that the Hooks are not called inside loops, conditions, or nested functions.
Also this rule ensures that the Hooks are called only from React function components or custom Hooks so that the stateful logic of a component is clearly visible from its source code.
Fix
The solution to fix all the 4 errors it to declare the hooks at the top of the function before executing any logic.
Concerned file: src/features/window/fileUtils.ts
What ?
Regex does not have the expected behaviour and is not adapted to multi OS.
Where ?
- Line 201: path = path.replace(/^/|/$/g, '')
- Line 203: path = path.replace(/\$/g, '')
- Line 205: path.replace(/^\/g, '')
Why ?
The first regex uses the pipe symbol | to match either a leading slash or a trailing slash and the g flag to perform a global match, which means it will replace all occurrences of the matched pattern. However, this regex will not remove any backslashes at the end or beginning of the string. The second and third regex are correct but only for Windows operating system.
Fix
// Remove trailing and leading slashes and backslashes path = path.replace(/^[/\]+|[/\]+$/g, '');
// Remove trailing backslashes path = path.replace(/[/\]+$/g, '');
// Remove leading backslashes path = path.replace(/^[/\]+/g, '');