reactjstransitionfadeouteffectpjax

How to get transaction effect in React.js Project?


I want a page transaction effect like : old page fade out and new page fade in. I am not sure how to do it and I need your help. If you have experiences on this field, please tell me.

Thanks.


Solution

  • This is a little complicated for begineers , you will need fadeInPage and fadeOutPage class , and you need to build a custom prop , to make delay before transition and maintain a context state to change to toggle fadeInPage and fadeOutPage class , make sure to maintain the seconds in React component and css same

    App.js

    
    import "./styles.css";
    import { Route, Switch, useHistory, useLocation, Link } from "react-router-dom";
    import Home from "./Home";
    import Apple from "./Apple";
    import { useState, useEffect, createContext, useReducer } from "react";
    export const FadeContext = createContext();
    
    const initialState = {
      fade: "fadeInPage"
    };
    
    const reducer = (state, action) => {
      switch (action.type) {
        case "FADEIN":
          return {
            ...state,
            fade: "fadeInPage"
          };
        case "FADEOUT":
          return {
            ...state,
            fade: "fadeOutPage"
          };
        default:
          return state;
      }
    };
    export const DelayLink = (props) => {
      const { delay, onDelayStart, onDelayEnd, replace, to, ...rest } = props;
      let timeout = null;
      let history = useHistory();
      let location = useLocation();
    
      useEffect(() => {
        return () => {
          if (timeout) {
            clearTimeout(timeout);
          }
        };
      }, [timeout]);
    
      const handleClick = (e) => {
        // if trying to navigate to current page stop everything
        if (location?.pathname === to) return;
    
        onDelayStart(e, to);
        if (e.defaultPrevented) {
          return;
        }
    
        e.preventDefault();
    
        timeout = setTimeout(() => {
          if (replace) {
            history.replace(to);
          } else {
            history.push(to);
          }
          onDelayEnd(e, to);
        }, delay);
      };
    
      return <Link {...rest} to={to} onClick={handleClick} />;
    };
    
    export default function App() {
      const [state, dispatch] = useReducer(reducer, initialState);
      const [fade, setFade] = useState(false);
    
      return (
        <FadeContext.Provider
          value={{
            state,
            dispatch
          }}
        >
          <div className="App">
            <span style={{ zIndex: "9999" }}>
              <DelayLink
                to={"/home"}
                replace={true}
                delay={2000}
                onDelayStart={() => {
                  dispatch({ type: "FADEOUT" });
                }}
                onDelayEnd={() => {
                  dispatch({ type: "FADEIN" });
                }}
                style={{ cursor: "pointer", textDecoration: "underline" }}
              >
                Home
              </DelayLink>
              <br />
              <DelayLink
                to={"/apple"}
                replace={false}
                delay={2000}
                onDelayStart={() => {
                  dispatch({ type: "FADEOUT" });
                }}
                onDelayEnd={() => {
                  dispatch({ type: "FADEIN" });
                }}
                style={{ cursor: "pointer", textDecoration: "underline" }}
              >
                Apple
              </DelayLink>
            </span>
    
            <Switch>
              <Route path={"/home"} exact fade={fade}>
                <Home />
              </Route>
              <Route path={"/apple"} fade={fade}>
                <Apple />
              </Route>
            </Switch>
          </div>
        </FadeContext.Provider>
      );
    }
    
    
    
    
    .App {
      font-family: sans-serif;
      text-align: center;
    }
    
    .fadeInPage {
      -webkit-animation: fadein 2s; /* Safari, Chrome and Opera > 12.1 */
      -moz-animation: fadein 2s; /* Firefox < 16 */
      -ms-animation: fadein 2s; /* Internet Explorer */
      -o-animation: fadein 2s; /* Opera < 12.1 */
      animation: fadein 2s;
    }
    
    .fadeOutPage {
      -webkit-animation: fadeout 2s; /* Safari, Chrome and Opera > 12.1 */
      -moz-animation: fadeout 2s; /* Firefox < 16 */
      -ms-animation: fadeout 2s; /* Internet Explorer */
      -o-animation: fadeout 2s; /* Opera < 12.1 */
      animation: fadeout 2s;
    }
    
    @keyframes fadein {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    /* Firefox < 16 */
    @-moz-keyframes fadein {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    /* Safari, Chrome and Opera > 12.1 */
    @-webkit-keyframes fadein {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    /* Internet Explorer */
    @-ms-keyframes fadein {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    /* Opera < 12.1 */
    @-o-keyframes fadein {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    @keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    
    /* Firefox < 16 */
    @-moz-keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    
    /* Safari, Chrome and Opera > 12.1 */
    @-webkit-keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    
    /* Internet Explorer */
    @-ms-keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    
    /* Opera < 12.1 */
    @-o-keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    
    

    There is a lot of code , so ref this repo for good understanding

    Edit proud-sound-0sjx2