Gatsby.js: Navigating with URL Parameters and the Browser Back / Forward Buttons

江枫思渺然 提交于 2019-12-05 05:45:16

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).

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

Edit:

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.

The code:

/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;

This can be resolved using history object present inside window object.

Another way is using the React-Router-DOM, which is the latest routing module for routing in ReactJS Applications. So for reference to V4 router follow this code.

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

After importing router, just try to scope your root Component inside it, then you can, create routes inside it.

  <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> 

keep in mind that router should contain only single child other wise, it won't work as expected. This way routing becomes very easy to work with.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!