繁体   English   中英

Next.js - 当 Router.push() 或 getInitialProps() 完成时执行回调

[英]Next.js - execute callback when Router.push() or getInitialProps() completes

我有一个页面,它在 2 秒后在getInitialProps()中生成一个随机数。 有一个按钮允许用户通过Router.push() “刷新”页面。 由于getInitalProps()需要 2 秒才能完成,因此我想显示一个加载指示器。

import React from 'react'
import Router from 'next/router'

export default class extends React.Component {
  state = {
    loading: false
  }

  static getInitialProps (context) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({random: Math.random()})
      }, 2000)
    })
  }

  render() {
    return <div>
      {
        this.state.loading
        ? <div>Loading</div>
        : <div>Your random number is {this.props.random}</div>
      }
      <button onClick={() => {
        this.setState({loading: true})
        Router.push({pathname: Router.pathname})
      }}>Refresh</button>
    </div>
  }
}

我如何知道Router.push() / getInitialProps()何时完成以便清除加载指示器?

编辑:使用Router.on('routeChangeComplete')是最明显的解决方案。 但是,有多个页面,用户可以多次单击按钮。 有没有安全的方法来为此使用路由器事件?

Router.push()返回一个 Promise。 所以你可以做一些像......

Router.push("/off-cliff").then(() => {
  // fly like an eagle, 'til I'm free
})

使用可以在pages/_app.js使用Router事件监听pages/_app.js ,管理页面加载和注入状态到组件

import React from "react";
import App, { Container } from "next/app";
import Router from "next/router";

export default class MyApp extends App {
  state = {
    loading: false
  };

  componentDidMount(props) {
    Router.events.on("routeChangeStart", () => {
      this.setState({
        loading: true
      });
    });

    Router.events.on("routeChangeComplete", () => {
      this.setState({
        loading: false
      });
    });
  }

  static async getInitialProps({ Component, ctx }) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    const { Component, pageProps } = this.props;
    return (
      <Container>
        {/* {this.state.loading && <div>Loading</div>} */}
        <Component {...pageProps} loading={this.state.loading} />
      </Container>
    );
  }
}

并且您可以在页面组件中将加载作为道具访问。

import React from "react";
import Router from "next/router";

export default class extends React.Component {
  static getInitialProps(context) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ random: Math.random() });
      }, 2000);
    });
  }

  render() {
    return (
      <div>
        {this.props.loading ? <div>Loading</div> : <div>Your random number is {this.props.random}</div>}
        <button
          onClick={() => {
            this.setState({ loading: true });
            Router.push({ pathname: Router.pathname });
          }}
        >
          Refresh
        </button>
      </div>
    );
  }
}

您还可以在_app.js显示加载文本(我已经评论过),这样您就不必检查每个页面的加载状态

如果你想在这里使用第三方包,一个很好的nprogress

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM