Gatsby.js:使用URL参数和浏览器后退/前进按钮进行导航 [英] Gatsby.js: Navigating with URL Parameters and the Browser Back / Forward Buttons

查看:140
本文介绍了Gatsby.js:使用URL参数和浏览器后退/前进按钮进行导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文章组件,其中显示了帖子列表.该列表是分页的,因此每页最多可以显示10个帖子.有一个下一页"按钮,单击该按钮将更新组件状态和相应的url参数,如下所示:

I have an Articles component which displays a list of posts. The list is paginated so that a maximum of 10 posts can display per page. There is a "Next Page" button that when clicked will update the component state and the corresponding url parameter like so:

第1页:/新闻

第2页:/news?page = 2

page 2: /news?page=2

第3页:/news?page = 3

page 3: /news?page=3

...等等.设置constructor()render()方法的方式,例如,如果用户直接导航到/news?page = 3,它将读取此URL参数并显示正确的帖子.

...and so on. The way the constructor() and render() methods are set up, it will read this URL parameter and display the correct posts if the user navigates directly to /news?page=3, for instance.

我遇到的问题是浏览器的后退和前进按钮似乎无法重新渲染页面.因此,如果用户多次单击下一页"按钮,然后单击后退按钮,则URL将更新,但页面不会重新呈现.有办法强迫它这样做吗?

The issue I'm having is that the browser back and forward buttons don't seem to rerender the page. So if a user hits the "Next Page" button a few times and then hits the back button, the URL will update, but the page won't rerender. Is there a way to force it to do so?

我猜想有一种方法可以通过添加window.history侦听器来实现,但是我不确定是否有推荐的做法与gatsby-link一起使用.

I'm guessing there's a way to accomplish this by adding a window.history listener, but I wasn't sure if there was a recommended practice to go along with gatsby-link.

以下是该组件的精简版本供参考:

Here is a stripped down version of the component for reference:

import React, { Component } from 'react';
import { navigateTo } from 'gatsby-link';
import getUrlParameter from '../functions/getUrlParameter';

export default class extends Component {
  constructor(props) {
    super(props);

    /* external function, will grab value
    * of ?page= url parameter if it exists */
    const urlParamPage = getUrlParameter('page');
    const currentPage = urlParamPage ? urlParamPage : 1;

    this.state = {
      currentPage
    };
  }

  nextPage() {
    const { props, state } = this;

    const urlParam = state.currentPage > 1
      ? `?page=${state.currentPage}`
      : '';

    navigateTo(props.pathname + urlParam);
    this.setState({currentPage: this.state.currentPage + 1});
  }

  render() {
    const { props, state } = this;

    const articles = props.articles
      .slice(state.currentPage * 10, state.currentPage * 10 + 10);

    return (
      <div>
        <ul>
          {articles.map((article) => <li>{article.title}</li>)}
        </ul>

        <button onClick={() => this.nextPage()}>Next Page</button>
      </div>
    );
  }
}

推荐答案

您的页面不会重新呈现,因为它实际上是同一页面-该组件已经安装.在constructor()中获取数据时,页面不会更新,因为React组件的构造函数在挂载之前被调用(

Your page doesn't rerender because it is actually the same page - the component is already mounted. As you are fetching your data in constructor(), your page won't update because the constructor for a React component is called before it is mounted (source).

您所说的urlParam只是componentWillReceiveProps(nextProps)应该在nextProps.location.search中接收的新道具.

What you call urlParam are just a new prop that componentWillReceiveProps(nextProps) should receive in nextProps.location.search.

您必须提升状态,因为只有根组件才能在浏览器的后退和前进按钮上收到props.location.您的Articles组件的pathname道具会发生神经变化,这就是为什么componentWillReceiveProps永远不会在此处触发的原因.

You have to lift state up because only the root component will receive props.location on browser back and forward buttons. The pathname prop of your Articles component nerver changes, that is why componentWillReceiveProps never fires here.

import React, { Component } from 'react';
import { navigateTo } from 'gatsby-link';

import Articles from '../components/Articles';

export default class Test extends Component {
  constructor(props) {
    super(props);

    this.state = {
      currentPage: 1,
      data: {}, // your ext data
    };

    this.nextPage = this.nextPage.bind(this);
  }

  nextPage() {
    const { currentPage } = this.state;
    const { pathname } = this.props.location;
    const url = `${pathname}?page=${currentPage + 1}`;

    this.setState({ currentPage: currentPage + 1 });
    navigateTo(url);
  }

  componentWillReceiveProps(nextProps) {
    const { pathname, search } = nextProps.location;
    const getParam = /(\d+)(?!.*\d)/;

    const currentPage = search !== '' ? Number(search.match(getParam)[0]) : 1;

    /* get your ext. data here */
    const data = {};

    this.setState({ currentPage, data });
  }

  render() {
    const { currentPage, data } = this.state;
    return (
      <div>
        {/* other contents here */}
        <Articles
          nextPage={this.nextPage}
          currentPage={currentPage}
          data={data}
        />
      </div>
    );
  }
}

/src/components/Articles.js

import React from 'react';

const Articles = ({ nextPage, currentPage }) => {
  return (
    <div>
      <div>Page: {currentPage}</div>
      <button onClick={() => nextPage()}>Next Page</button>
    </div>
  );
};

export default Articles;

这篇关于Gatsby.js:使用URL参数和浏览器后退/前进按钮进行导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆