如何在反应路由中设置延迟功能



如何在 React 上设置延迟函数.js?有没有办法在反应路由中添加或删除类,以便页面可以转换?添加、删除或切换类应该每次都有效。是否可以使用延迟功能在路由上添加、删除或切换类?或者我可以使用第三方库吗?

 import React from "react";
    import { BrowserRouter as Router, Route, Link } from "react-router-dom";
    
    const BasicExample = () => (
      <Router>
        <div>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/topics">Topics</Link>
            </li>
          </ul>
    
          <hr />
    
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
        </div>
      </Router>
    );
    
    const Home = () => (
      <div>
        <h2>Home</h2>
      </div>
    );
    
    const About = () => (
      <div>
        <h2>About</h2>
      </div>
    );
    
    const Topics = ({ match }) => (
      <div>
        <h2>Topics</h2>
        <ul>
          <li>
            <Link to={`${match.url}/rendering`}>Rendering with React</Link>
          </li>
          <li>
            <Link to={`${match.url}/components`}>Components</Link>
          </li>
          <li>
            <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
          </li>
        </ul>
    
        <Route path={`${match.url}/:topicId`} component={Topic} />
        <Route
          exact
          path={match.url}
          render={() => <h3>Please select a topic.</h3>}
        />
      </div>
    );
    
    const Topic = ({ match }) => (
      <div>
        <h3>{match.params.topicId}</h3>
      </div>
    );
    
    export default BasicExample;

我将Paul的上述答案修改为更新的功能组件:

import React, { useEffect } from "react";
import PropTypes from "prop-types";
import { Link, useHistory, useLocation } from "react-router-dom";
// Functional link component which delays page navigation
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} />;
};
DelayLink.propTypes = {
  // Milliseconds to wait before registering the click.
  delay: PropTypes.number,
  // Called after the link is clicked and before the delay timer starts.
  onDelayStart: PropTypes.func,
  // Called after the delay timer ends.
  onDelayEnd: PropTypes.func,
  // Replace history or not
  replace: PropTypes.bool,
  // Link to go to
  to: PropTypes.string
};
DelayLink.defaultProps = {
  replace: false,
  delay: 0,
  onDelayStart: () => {},
  onDelayEnd: () => {}
};
export default DelayLink;

要点

https://gist.github.com/headzoo/8f4c6a5e843ec26abdcad87cd93e3e2e

import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
/**
 * Wraps the React Router Link component and creates a delay after the link is clicked.
 */
export default class DelayLink extends React.Component {
  static propTypes = {
    /**
     * Milliseconds to wait before registering the click.
     */
    delay:        PropTypes.number,
    /**
     * Called after the link is clicked and before the delay timer starts.
     */
    onDelayStart: PropTypes.func,
    /**
     * Called after the delay timer ends.
     */
    onDelayEnd:   PropTypes.func
  };
  static defaultProps = {
    delay:        0,
    onDelayStart: () => {},
    onDelayEnd:   () => {}
  };
  static contextTypes = Link.contextTypes;
  constructor(props) {
    super(props);
    this.timeout = null;
  }
  componentWillUnmount() {
    if (this.timeout) {
      clearTimeout(this.timeout);
    }
  }
  /**
   * Called when the link is clicked
   *
   * @param {Event} e
   */
  handleClick = (e) => {
    const { replace, to, delay, onDelayStart, onDelayEnd } = this.props;
    const { history } = this.context.router;
    onDelayStart(e, to);
    if (e.defaultPrevented) {
      return;
    }
    e.preventDefault();
    this.timeout = setTimeout(() => {
      if (replace) {
        history.replace(to);
      } else {
        history.push(to);
      }
      onDelayEnd(e, to);
    }, delay);
  };
  render() {
    const props = Object.assign({}, this.props);
    delete props.delay;
    delete props.onDelayStart;
    delete props.onDelayEnd;
    return (
      <Link {...props} onClick={this.handleClick} />
    );
  }
}
对我来说,

这是我一直使用的最清晰的方式

import { useNavigate } from "react-router-dom";
function Component() {
const navigate = useNavigate()
// this is a function which returning a promise in the requested time
function wait(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time);
  });
}
// this is the routing function
async function goToPage() {
    // it will navigate to the page 500ms after clicing the div
    await wait(500);
    navigate(`/movie/${whatever}`);
  }
return <div onClick={goToPage}>
}

最近遇到了我需要解决的相同问题。制作此软件包是为了帮助任何需要做同样事情的人。

https://www.npmjs.com/package/delay-react-route-exit

我将Kim的上述答案修改为v5钩子(useHistory(的v6钩子(useNavigate(。

import { Link, useNavigate, useLocation } from "react-router-dom";
...
...
let navigate = useNavigate();
...
...
timeout = setTimeout(() => {
      if (replace) {
        navigate(to, { replace: true });
      } else {
        navigate(to);
      }
      onDelayEnd(e, to);
    }, delay);

要点

最新更新