Gatsby.js: Navigation with URL parameters and Back / Forward Browser buttons

I have an Articles component that displays a list of posts. The list is paginated so that a maximum of 10 posts can be displayed on each page. There is a “Next Page” button that, when clicked, will update the state of the component and the corresponding URL parameter as follows:

page 1: / news

p. 2: / news? page = 2

page 3: / news? page = 3

... etc. The way that the constructor()and methods are configured render()will read this URL parameter and display the correct messages if the user, for example, navigates directly to / news? Page =.

The problem I am facing is that the browser buttons back and forth do not display the page. Therefore, if the user clicks the Next Page button several times and then clicks the Back button, the URL will be updated, but the page will not be reloaded. Is there any way to get this to do this?

I suppose there is a way to do this by adding a window.history listener, but I was not 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>
    );
  }
}
+6
source share
2 answers

, - . constructor(), , React (source).

, urlParam, , componentWillReceiveProps(nextProps) nextProps.location.search.

Edit:

, props.location . pathname nerver , componentWillReceiveProps .

:

/src/pages/root.js

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;
+4

, , .

- React-Router-DOM, ReactJS. V4 .

  import {BrowserRouter as Router, Route, Switch, Redirect} from 'react-router-dom';

, .

  <Router>
    <div className="App" id="App">
      <Route path="/" exact component={Home}/>
      <Route path="/about" exact component={About}/>  
      <Route path="/misreports" exact component={MISReport}/>  
      <Route path="/contact" exact component={Contact}/>  
    </div>
  </Router> 

, , . , .

+1

All Articles