Introduce eslint-plugin-react-hooks

This commit is contained in:
Kalle 2022-03-30 19:58:08 +03:00
parent 05fb292a54
commit e2dda84d83
12 changed files with 44 additions and 13 deletions

View File

@ -12,6 +12,7 @@ module.exports = {
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended",
],
rules: {
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],

View File

@ -30,14 +30,16 @@ export default function useChat(id: string) {
setUnreadCount((count) => count + 1);
}
},
[isOpen]
[isOpen, user.id]
);
useSocketEvent(`chat-${id}`, eventHandler);
React.useEffect(() => {
loaderFetcher.load(chatRoute([id]));
}, []);
// TODO: should also have loaderFetcher
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id]);
// open chat on data load if there are messages
React.useEffect(() => {
@ -59,10 +61,10 @@ export default function useChat(id: string) {
React.useEffect(() => {
if (!actionFetcher.data) return;
setMessagesAfterLoad([
...messagesAfterLoad,
actionFetcher.data.createdMessage,
]);
setMessagesAfterLoad((messagesAfterLoad) => {
if (!actionFetcher.data) return [...messagesAfterLoad];
return [...messagesAfterLoad, actionFetcher.data.createdMessage];
});
}, [actionFetcher.data]);
const messages = React.useMemo(

View File

@ -16,7 +16,10 @@ export default function Modal({
const navigate = useNavigate();
const ref = React.useRef<HTMLDivElement>(null);
const navigateBack = React.useCallback(() => navigate(closeUrl), [closeUrl]);
const navigateBack = React.useCallback(
() => navigate(closeUrl),
[closeUrl, navigate]
);
useOnClickOutside(ref, navigateBack);
React.useEffect(() => {

View File

@ -23,7 +23,9 @@ export function SubmitButton(
onSuccess?.();
setShowSuccess(true);
}, [actionData?.ok, transition.type]);
// TODO: should also have onSuccess
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [actionData?.ok, transition.type, actionType, setShowSuccess]);
const isLoading = (): boolean => {
// is there an action happening at the moment?

View File

@ -21,13 +21,13 @@ export function CheckinActions() {
const user = useUser();
const transition = useTransition();
const timeInMinutesBeforeCheckInCloses = () => {
const timeInMinutesBeforeCheckInCloses = React.useCallback(() => {
return Math.floor(
(checkInClosesDate(tournament.startTime).getTime() -
new Date().getTime()) /
(1000 * 60)
);
};
}, [tournament.startTime]);
const [minutesTillCheckInCloses, setMinutesTillCheckInCloses] =
React.useState(timeInMinutesBeforeCheckInCloses());

View File

@ -1,4 +1,5 @@
import { hydrate } from "react-dom";
import { RemixBrowser } from "remix";
// TODO: should this be hydrateRoot?
hydrate(<RemixBrowser />, document);

View File

@ -56,7 +56,7 @@ export function useBracketDataWithEvents(): BracketModified {
})),
});
},
[data, setDataWithEvents]
[dataWithEvents, setDataWithEvents]
);
useSocketEvent(`bracket-${data.id}`, eventHandler);

View File

@ -12,5 +12,5 @@ export function useSocketEvent(event: string, handler: (data: any) => void) {
return () => {
socket.off(event);
};
}, [socket, handler]);
}, [socket, handler, event]);
}

View File

@ -59,6 +59,7 @@ export default function App() {
const children = React.useMemo(() => <Outlet />, []);
const data = useLoaderData<RootLoaderData>();
// TODO: for future optimization could only connect socket on sendouq/tournament pages
React.useEffect(() => {
const socket = io();
setSocket(socket);

View File

@ -190,7 +190,7 @@ function SeedAlert({
setTeamOrderInDb(teamOrder);
setShowSuccess(true, { timeout: 3000 });
}, [transition.state]);
}, [transition.state, setShowSuccess, teamOrder]);
const teamOrderChanged = teamOrder.some((id, i) => id !== teamOrderInDb[i]);

20
package-lock.json generated
View File

@ -58,6 +58,7 @@
"cypress": "^9.5.3",
"eslint": "^8.12.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"nodemon": "^2.0.15",
"npm-run-all": "^4.1.5",
"prettier": "2.6.1",
@ -4307,6 +4308,18 @@
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz",
"integrity": "sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ==",
"dev": true,
"engines": {
"node": ">=10"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
}
},
"node_modules/eslint-plugin-react/node_modules/doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@ -15330,6 +15343,13 @@
}
}
},
"eslint-plugin-react-hooks": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz",
"integrity": "sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ==",
"dev": true,
"requires": {}
},
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",

View File

@ -78,6 +78,7 @@
"cypress": "^9.5.3",
"eslint": "^8.12.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"nodemon": "^2.0.15",
"npm-run-all": "^4.1.5",
"prettier": "2.6.1",