Skip to content

Instantly share code, notes, and snippets.

@headzoo
Created July 30, 2017 19:20
Show Gist options
  • Save headzoo/8f4c6a5e843ec26abdcad87cd93e3e2e to your computer and use it in GitHub Desktop.
Save headzoo/8f4c6a5e843ec26abdcad87cd93e3e2e to your computer and use it in GitHub Desktop.
Wraps the React Router Link component and creates a delay after the link is clicked.
@ClementKerneur
Copy link

Hi @headzoo
Thanks for this component.

I've used your component to add a class into my root element, so fadeout effect is now possible.

<DelayLink 
    to="/next_page"
    delay={800}
    onDelayStart={() => { /* fadeout class */ }}
    onDelayEnd={() => { /* fadein class */ }} />

A little bit of css and transition effect is ready.

Have a good day

@pig800509
Copy link

pig800509 commented Jul 15, 2020

updated with hook

import React, { useEffect, useCallback, useState } from "react";
import PropTypes from "prop-types";
import { Link, useHistory } from "react-router-dom";

const DelayLink = (props) => {
	let [isTimeOut, setIsTimeout] = useState(false);
	let history = useHistory();
	const { replace, to, delay, onDelayStart, onDelayEnd, children } = props;

	useEffect(() => {
		if (isTimeOut) {
			let delayTimeOut = setTimeout(() => {
				if (replace) {
					history.replace(to);
				} else {
					history.push(to);
				}
				onDelayEnd();
			}, delay);

			return () => clearTimeout(delayTimeOut);
		}
	}, [delay, history, onDelayEnd, replace, to, isTimeOut]);
	const handleClick = useCallback(
		(e) => {
			onDelayStart(e, to);
			if (e.defaultPrevented) {
				return;
			}
			e.preventDefault();
			setIsTimeout(true);
		},
		[to, onDelayStart]
	);

	return (
		<Link
			to={props.to}
			delay={props.delay}
			onClick={handleClick}
			replace={props.replace}>
			{children}
		</Link>
	);
};

DelayLink.prototype = {
	to: PropTypes.string.isRequired,
	delay: PropTypes.number,
	onDelayStart: PropTypes.func,
	onDelayEnd: PropTypes.func,
	replace: PropTypes.bool
};
DelayLink.defaultProps = {
	delay: 0,
	onDelayStart: () => {},
	onDelayEnd: () => {}
};

export default DelayLink;

@ClydeFrog04
Copy link

pig800509 your code is a good idea, I like the idea of having a functional component version, but it seems to be missing some things, so I went ahead and corrected what was missing(eslint caught some stuff) and once I got it functional I get this error. Just wanted to mention it if anyone else comes across it. The class component version worked like a charm though!
image

@pig800509
Copy link

pig800509 commented Aug 21, 2020

@ClydeFrog04, sorry, I have fixed that issue, try again.

thanks

@romiem
Copy link

romiem commented Oct 8, 2020

Another thing this component is missing is the ability to carry over props such as className or onLeave etc. Is there a clean way to do this whilst still maintaining typescript support for these props?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment