Search code examples
reactjstypescriptreduxreact-redux

How get get State objects when performing beforeunload in React


I have this object that I'm trying to save to an session persisted array with the beforeunload event

  const { serviceRequest, serviceRequestOriginal, isDirty } = useAppSelector((state) => state.csmRequestDataReducer);

  useEffect(() => {
    
    window.addEventListener("beforeunload", (event) => {
      console.log('beforeunload:' + isDirty);
      console.log(current(serviceRequest));
      console.log('beforeunload:' + isDirty);
      dispatch(persistRequestTab({ currentSRCurrentState: isDirty ? serviceRequest : null, currentSRPreviousState: isDirty ? serviceRequestOriginal : null }));
      console.log("API call before page reload");
    });
    
  }, []);

However the console output shows serviceRequest = null and isDirty = false.

Why is this and can I alter/fix to get these objects/values?


Solution

  • Ok so I don't know if this is a perfect resolution however it seems to work really well.

    When creating the event listener it locks in the initial state objects values, using a reference useRef() will get around this, just make sure to update the reference as state is updated with some more useEffects.

      const { serviceRequest, serviceRequestOriginal, isDirty } = useAppSelector((state) => state.csmRequestDataReducer);
      const currentSRRef = useRef<ServiceRequest | null>(serviceRequest);
      const currentSROrigRef = useRef<ServiceRequest | null>(serviceRequestOriginal);
      const currentIsDirtyRef = useRef<boolean>(isDirty);
      
      useEffect(() => {
        
        window.addEventListener("beforeunload", (event) => {
          console.log('beforeunload:' + currentIsDirtyRef.current);
          dispatch(persistRequestTab({ currentSRCurrentState: currentIsDirtyRef.current ? currentSRRef.current : null, currentSRPreviousState: currentIsDirtyRef.current ? currentSROrigRef.current : null }));
        });
        
      }, []);
    
      useEffect(() => {
        currentSRRef.current = serviceRequest;
        currentIsDirtyRef.current = isDirty;
      }, [serviceRequest])
    
      useEffect(() => {
        currentSROrigRef.current = serviceRequestOriginal;
      }, [serviceRequestOriginal])