I understand that without dependencies you cannot access state inside useEffect. An example as such :
const [state, setState] = React.useState('')
const ws = new WebSocket(`ws://localhost:5000`)
React.useEffect(() => {
ws.onopen = () => {
console.log(state)
},[])
In this case state comes back as empty even though it has changed in other parts of the code. To solve this in principle I should add state as dependency to the useEffect hook. However, this will trigger the listener again and I do not want to have 2 active listeners on my websocket or being forced to close and reopen it again as such :
React.useEffect(() => {
ws.onopen = () => {
console.log(state)
},[state])
What is good practice when it comes to accessing state inside a listener that sits inside useEffect hook?
CodePudding user response:
Try this approach:
const [state, setState] = React.useState('');
const stateRef = React.useRef(state);
React.useEffect(() => {
stateRef.current = state;
}, [state])
const ws = React.useMemo(() => {
const newWS = new WebSocket(`ws://localhost:5000`);
newWS.onopen = () => {
console.log(stateRef.current);
}
return newWS;
}, []);
This way you create the ws only once, and it will use the state reference which will be up to date because of the useEffect.
If you don't need to re-render the component when the state updates you can remove const [state, setState] = React.useState(''); and the useEffect and just update the stateRef like this when you need - stateRef.current = newValue;
CodePudding user response:
Best Practice get data in listeners.[UPDATED]!
const [socketData , setSocketData] = useState(null);
useEffect(() => {
websocet.open( (data) => {
setSocketData(data);
})
},[])
//second useEffect to check socketData
useEffect(() => {
if(socketData){
// access to data which come from websock et
}
},[socketData])
