Issue 1:
feature request: getState, example, const [state, setState, getState] = useState(null);

it is ok to use the simple variable in a dependent uses effect, but not ok in not a dependant use effect.

the state is a simple variable. which is closure passed into functions, so it is not updated.

and setState with a function argument is asynchronously dispatched.

I suggest adding a synchronous function getState.

it will be useful in simple js functions that are defined in useEffect for integration with not react js

const [audioTrack, setAudioTrack] = useState(null);
const [savedSelectedAudioTrack, setSavedSelectedAudioTrack] = useState(null);
const [audioContext, setAudioContext] = useState(null);

// use useEffect to run once
useEffect( () =>{
const handleParticipant = (participant) => {

const availableTracks = Array.from(
participant.tracks.values()
).filter(
(publication) => publication.isSubscribed,
).map(
(publication) => publication.track,
);

const audioTracks = availableTracks.filter(
(track) => track.kind === 'audio',
);

const selectedAudioTrack =
audioTracks.length === 0 ? null : audioTracks[0];

if (selectedAudioTrack !== savedSelectedAudioTrack) { // here savedSelectedAudioTrack will not work
setSavedSelectedAudioTrack(selectedAudioTrack);
if (audioContext)
setAudioTrack(
// eslint-disable-next-line prettier/prettier
audioContext.MediaStreamAudioSourceNode(selectedAudioTrack)
);
else setTimeout(() => handleParticipant(participant), 100);

// setSelectedAudioTrack(selectedAudioTrack1);
window.hasAudioTrack = true;
} else {
window.hasAudioTrack = false;
}

console.log(
'audioTracks.length:',
audioTracks.length
);
};

// create audiocontext and 3rd parity library and add event handler to 3rd parity library
setAudioContext(createdAudioContext);
3rdParityLibrary.handleEvent=handleParticipant ;
} ,[])

but the working implementation is like

const [audioTrack, setAudioTrack] = useState(null);
const [savedSelectedAudioTrack, setSavedSelectedAudioTrack] = useState(null);
const [audioContext, setAudioContext] = useState(null);

// use useEffect to run once
useEffect( () =>{
const handleParticipant = (participant) => {

setSavedSelectedAudioTrack((savedSelectedAudioTrack) => {
setAudioContext((audioContext) => {

const availableTracks = Array.from(
participant.tracks.values()
).filter(
(publication) => publication.isSubscribed,
).map(
(publication) => publication.track,
);

const audioTracks = availableTracks.filter(
(track) => track.kind === 'audio',
);

const selectedAudioTrack =
audioTracks.length === 0 ? null : audioTracks[0];

if (selectedAudioTrack !== savedSelectedAudioTrack) { // here savedSelectedAudioTrack will not work
setSavedSelectedAudioTrack(selectedAudioTrack);
if (audioContext) // and audio context also will not work
setAudioTrack(
// eslint-disable-next-line prettier/prettier
audioContext.MediaStreamAudioSourceNode(selectedAudioTrack)
);
else setTimeout(() => handleParticipant(participant), 100);

// setSelectedAudioTrack(selectedAudioTrack1);
window.hasAudioTrack = true;
} else {
window.hasAudioTrack = false;
}

console.log(
'audioTracks.length:',
audioTracks.length
);

return audioContext;
});
return savedSelectedAudioTrack;
});
};

// create audiocontext and 3rd parity library and add event handler to 3rd parity library
setAudioContext(createdAudioContext);
3rdParityLibrary.handleEvent=handleParticipant ;
} ,[])

i wish there was a synchronous getState.

const [audioTrack, setAudioTrack] = useState(null);
const [savedSelectedAudioTrack, setSavedSelectedAudioTrack, getSavedSelectedAudioTrack] = useState(null);
const [audioContext, setAudioContext, getAudioContext] = useState(null);

// use useEffect to run once
useEffect( () =>{
const handleParticipant = (participant) => {

const availableTracks = Array.from(
participant.tracks.values()
).filter(
(publication) => publication.isSubscribed,
).map(
(publication) => publication.track,
);

const audioTracks = availableTracks.filter(
(track) => track.kind === 'audio',
);

const selectedAudioTrack =
audioTracks.length === 0 ? null : audioTracks[0];

if (selectedAudioTrack !== getSavedSelectedAudioTrack()) { // here savedSelectedAudioTrack will not work
setSavedSelectedAudioTrack(selectedAudioTrack);
if (getAudioContext())
setAudioTrack(
getAudioContext().MediaStreamAudioSourceNode(selectedAudioTrack)
);
else setTimeout(() => handleParticipant(participant), 100);

// setSelectedAudioTrack(selectedAudioTrack1);
window.hasAudioTrack = true;
} else {
window.hasAudioTrack = false;
}

console.log(
'audioTracks.length:',
audioTracks.length
);
};

// create audiocontext and 3rd parity library and add event handler to 3rd parity library
setAudioContext(createdAudioContext);
3rdParityLibrary.handleEvent=handleParticipant ;
} ,[])

Issue 2:
Steps To Reproduce

Englobe code in a static class make rule bug !

Actually rule detect React in class, but it not true !

This is a pure ES6 js class with a proxi field to a React functions in scope.

And is not a React Class components !

interface PanelProps {}
class DOMAINE {
static Panel : FC<PanelProps> = (props)=> {
const { children } = props;
const state = useState<unknown>(null);

useEffect(() => {});
return (
<Bloc className='Panel' Flex Grow>
{children}
</Bloc>
);
};
static a = class ACTIVITY {
static Panel : VFC<PanelProps> = (props)=> {
const { } = props;
const state = useState<unknown>(null);

useEffect(() => {});
return (
<Bloc className='Panel' Flex Grow>

</Bloc>
);
};
}
}

{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
"array-bracket-spacing": "warn",
"multiline-comment-style": "warn",
"no-console": "warn",
"comma-dangle": "off",
"no-var": "warn",
"no-duplicate-imports": "error"
}
}

Link to code example: https://codesandbox.io/s/currying-https-9v064?file=/src/App.js

The current behavior

Rule think we use hooks inside a react Class !

The expected behavior

Rule should not emit error about hooks for this structure