I'm building a video calling feature into my app and the user's media stream is stored in a React state. However, when I try to access this state in another file (I'm using React Context for this), the stream state hasn't been updated yet and uses the default state value. I learnt, React updates state on the next render rather than instantly but I'm trying to access the stream instantly. However, I'm creating the Peer object inside a function so if I try to delay the stream access for example with a useEffect hook, I then can't use the function outside the hook. Are there any ways I could to this? Some code samples below:
Within context file:
const [stream, setStream] = useState(null)
Where I'm setting the stream:
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((currentStream) => {
setStream(currentStream);
}).catch((error) => {
console.log('Error accessing media devices: ', error);
});
}, []);
One of my functions (stream logs null):
function callUser(id) {
console.log(stream)
const peer = new Peer({ initiator: true, trickle: false, stream })
peer.on('signal', (data) => {
socket.emit('call-user', { userToCall: id, signalData: data, from: myID, name })
})
peer.on('close', () => {
socket.off('call-answered')
setCallAccepted(false)
setCall(null)
addCall(false)
setInfoBarShow(false)
})
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream
})
socket.on('call-answered', (signal) => {
setCallAccepted(true)
peer.signal(signal)
})
socket.on('call-ended', (endReason) => {
if (statusRef.current) {
if (endReason === "declined" || endReason === "ended") statusRef.current.innerHTML = `Call ${endReason}`
}
setTimeout(() => {
leaveCall()
}, 5000)
})
connectionRef.current = peer
}
I've tried lots of things such as wrapping the functions in a useEffect hook with the dependency as stream but then the functions aren't globally available. I've tried using selection but that won't work as the component still isn't being re-rendered/refreshed to include the updated state. Nothing works. For handling the WebRTC side of things I'm using the Simple-Peer package
To clarify: A button calls the function callUser. I'm accessing the stream state inside this function where I pass it into the Peer object for Simple-Peer. That stream value currently is using the default state of null that I set, not a MediaStream as it hasn't updated yet and that's my issue