最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Unique url for pagination pages in React - Stack Overflow

programmeradmin6浏览0评论

I need unique url for pages of pagination.

When I click to number of page in pagination - url is changed, like .../album/1/page/(number of choosen page) - and it is ok, but when I try to copy my url and paste it like (.../album/1/page/2), my app still load first page.

I need opportunity to load any pages from url.

This is my route for this moment:

<Route path="album/:id" ponent={AlbumsShow}>
    <Route path="page/:newPage" ponent={AlbumsShow} />
</Route>

And this is ponent:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import Pager from 'react-pager';
import {browserHistory} from 'react-router';

class AlbumsShow extends Component {
    constructor(props) {
        super(props);
        this.renderImage = this.renderImage.bind(this);
        this.handlePageChanged = this.handlePageChanged.bind(this);

        this.state = {
            total:       3,
            current:     0,
            visiblePage: 2,
        };
    }

    handlePageChanged(newPage) {
        this.setState({ current : newPage });
        browserHistory.push({
                pathname: (newPage+1),
            });
    }

    renderImage() {
        const imgs = this.props.images.length > 10 ?
              this.props.images.slice(this.state.current * 10, (this.state.current + 1) * 10) :
              this.props.images;
                return imgs.map((image, page) => (
                  <li className="image_list" key={image.id}>
                    <img className="image_list_img" alt="item" src={image.img} />
                  </li>
        ));
    }

    render() {
        return (
            <div className="wrapper">
              <ul>
                {this.renderImage()}
              </ul>

              {this.props.images.length > 10 ?

                <Pager
                  total={this.state.total}
                  current={this.state.current}
                  visiblePages={this.state.visiblePage}
                  titles={{ first: 'First page', last: 'Last page' }}
                  onPageChanged={this.handlePageChanged} 
                /> : null
              }
            </div>
        );
    }
}

function mapStateToProps(state, ownProps) {
    const currentAlbumId = parseInt(ownProps.params.id, 10);

    return {
        images: state.main.albums.filter(album => album.id === currentAlbumId)[0].images,
    };
}
export default connect(mapStateToProps)(AlbumsShow);

I need unique url for pages of pagination.

When I click to number of page in pagination - url is changed, like .../album/1/page/(number of choosen page) - and it is ok, but when I try to copy my url and paste it like (.../album/1/page/2), my app still load first page.

I need opportunity to load any pages from url.

This is my route for this moment:

<Route path="album/:id" ponent={AlbumsShow}>
    <Route path="page/:newPage" ponent={AlbumsShow} />
</Route>

And this is ponent:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import Pager from 'react-pager';
import {browserHistory} from 'react-router';

class AlbumsShow extends Component {
    constructor(props) {
        super(props);
        this.renderImage = this.renderImage.bind(this);
        this.handlePageChanged = this.handlePageChanged.bind(this);

        this.state = {
            total:       3,
            current:     0,
            visiblePage: 2,
        };
    }

    handlePageChanged(newPage) {
        this.setState({ current : newPage });
        browserHistory.push({
                pathname: (newPage+1),
            });
    }

    renderImage() {
        const imgs = this.props.images.length > 10 ?
              this.props.images.slice(this.state.current * 10, (this.state.current + 1) * 10) :
              this.props.images;
                return imgs.map((image, page) => (
                  <li className="image_list" key={image.id}>
                    <img className="image_list_img" alt="item" src={image.img} />
                  </li>
        ));
    }

    render() {
        return (
            <div className="wrapper">
              <ul>
                {this.renderImage()}
              </ul>

              {this.props.images.length > 10 ?

                <Pager
                  total={this.state.total}
                  current={this.state.current}
                  visiblePages={this.state.visiblePage}
                  titles={{ first: 'First page', last: 'Last page' }}
                  onPageChanged={this.handlePageChanged} 
                /> : null
              }
            </div>
        );
    }
}

function mapStateToProps(state, ownProps) {
    const currentAlbumId = parseInt(ownProps.params.id, 10);

    return {
        images: state.main.albums.filter(album => album.id === currentAlbumId)[0].images,
    };
}
export default connect(mapStateToProps)(AlbumsShow);
Share Improve this question asked May 25, 2017 at 13:42 bip-bopbip-bop 1,3212 gold badges16 silver badges27 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

Please use the page number from the routing props, that is :newPage and map it in mapStateToProps as pageNumber (optionally).

function mapStateToProps(state, ownProps) {
  const currentAlbumId = parseInt(ownProps.params.id, 10);
  const pageNumber = parseInt(ownProps.params.newPage, 10);

  return {
      pageNumber,
      images: state.main.albums.filter(album => album.id === currentAlbumId)[0].images,
  };
}

Then, instead of storing page number in the ponent's state, consume it as a prop.

<Pager current={this.props.pageNumber} ... />

When handling transition to the next page, just notify your router, don't store the state on your own. Your ponent will be re-rendered with the new pageNumber value.

handlePageChanged(newPage) {
    const { id } = this.props.params
    const { pageNumber } = this.props

    const target = `/albums/${id}/page/${pageNumber + 1}`

    browserHistory.push({
        pathname: target,
    });
}

All the way down, change occurrences of this.state.current to this.props.pageNumber and you are good to go.

The URL now bees the single source of truth.


Note: you can change routing parameters to better match their meaning:

<Route path="album/:albumId" ponent={AlbumsShow}>
    <Route path="page/:pageIndex" ponent={AlbumsShow} />
</Route>

After that you just consume those ids without mapping:

const { albumId, pageIndex } = this.props.params

You could check for the page param inside ponentWillReceiveProps and set that as the current state, which is then updates the Pager ponent.

ponentWillReceiveProps(newProps) {
  const { newPage } = newProps.params;
  if (newPage !== this.state.current) {
    this.setState({ current: page });
  }
}
发布评论

评论列表(0)

  1. 暂无评论