Closed
Description
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 ;
} ,[])