Skip to content

Commit

Permalink
Update docs and changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscerie committed Sep 20, 2023
1 parent 1a174ca commit 690ab9a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Added `no-exclude` cli flag to disable excludes.
- When given in standard library format, additional information now shows up in `incorrect_standard_library_use` missing required parameter errors.
- Added new [`mixed_table` lint](https://kampfkarren.github.io/selene/lints/mixed_table.html), which will warn against mixed tables.
- Added new [`roblox_roact_non_exhaustive_deps` lint](https://kampfkarren.github.io/selene/lints/roblox_roact_non_exhaustive_deps.html), which will check for valid dependency arrays.

### Fixed
- `string.pack` and `string.unpack` now have proper function signatures in the Lua 5.3 standard library.
Expand Down
61 changes: 61 additions & 0 deletions docs/src/lints/roblox_roact_non_exhaustive_deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# roblox_roact_non_exhaustive_deps
## What it does
Checks for valid dependency arrays. Verifies that dependencies are [reactive values](https://react.dev/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) and that upvalues referenced in hooks with dependency arrays are included in the array.

## Why this is bad
Hooks that are missing dependencies will read stale values and cause bugs.

## Example
```lua
local function Component(props)
React.useEffect(function()
print(props)
end) -- ok

React.useEffect(function()
print(props)
end, {}) -- Missing `props`

React.useEffect(function()
print(props.a)
end, { props.a }) -- ok

React.useEffect(function()
print(props.a)
end, { props.a.b }) -- Missing `props.a`

React.useEffect(function()
print(props.a())
end, { props.a() }) -- Too complex, extract `props.a()` to variable

local a1 = props.a()
React.useEffect(function()
print(a1)
end, { a1 }) -- now ok

React.useEffect(function()
print(props[a])
end, { props[a] }) -- Too complex, extract `props[a]` to variable

local a2 = props[a]
React.useEffect(function()
print(a2)
end, { a2 }) -- now ok

React.useEffect(function()
print(props)
end, helperFunction(props)) -- ok
end
```

## Remarks
1. This lint assumes either Roact or React is defined. [`undefined_variable`](./undefined_variable.md) will still lint, however.
2. This lint assumes the hook is prefixed with either `React`, `Roact`, `hooks` for legacy Roact, or a variable assigned to them.
3. This lint only takes effect for `useEffect`, `useMemo`, `useCallback`, and `useLayoutEffect`. Custom hooks that take dependency arrays will not lint.
4. This lint does not take effect if nothing is passed to the second argument of the hook.
5. This lint is only active if you are using the Roblox standard library.
6. This lint warns against complex dependency expressions like function calls and dynamic indexing. This currently false negatives with function calls without any indexing, such as `{ a() }`.

## Deviations from [eslint-plugin-react-hooks/exhaustive-deps](https://www.npmjs.com/package/eslint-plugin-react-hooks)
1. ESLint requires passing in `a` for `a.b()` since js can implicitly pass `a` as `this` to `a.b`. Lua doesn't do this, so we allow `a.b` as dependencies.
2. ESLint complains about brackets in dependencies like `a["b"]` as being too complex. If string literals are inside the brackets and not a variable like `a[b]`, we recognize that and treat it the same as `a.b`.

0 comments on commit 690ab9a

Please sign in to comment.