N
N
Nikolai2019-02-24 23:09:21
React
Nikolai, 2019-02-24 23:09:21

Why does Route fire twice?

I am using Browser Router. There is a menu with Links. When you click on one of them, the corresponding Route is triggered once. There is an item in the Categories menu, where product categories are displayed, since there are a lot of them, I had to use pagination, so there are two routes, one that works when you click in the menu ("/categories"), and the second when you click on an item in pagination ( "/categories/:page").
If we click on Categories, "/categories" will work once. Then it will go, for example, to the 2nd page "/categories/2" the corresponding route "/categories/:page" will work once. But if we now click on the Categories again, the "/categories" route will fire twice already. Why?

Menu
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Container, Menu } from "semantic-ui-react";

class View extends Component {
  render() {
    const { items, pathname } = this.props;

    return (
      <div className="mainmenu-component">
        <Container>
          <Menu stackable borderless>
            {items.map(item => (
              <Menu.Item
                key={item._id}
                active={pathname === "/" + item.url}
                as={Link}
                to={"/" + item.url}
              >
                {item.name}
              </Menu.Item>
            ))}
          </Menu>
        </Container>
      </div>
    );
  }
}

export default View;
Routes
import React from "react";
import { Route, Switch } from "react-router-dom";
import {
  Home,
  Categories,
  Category,
  Reviews,
  Blog,
  Contacts,
  AnotherPage,
} from "Components";

const Routes = () => {
  return (
    <Switch>
      <Route exact path="/" component={Home} />

      <Route
        exact
        path="/categories"
        render={() => {
          return (
            <Categories
              currentIndexPage={1}
              currentPathname="categories"
              pathToCategory="category"
            />
          );
        }}
      />

      <Route
        exact
        path="/categories/:page"
        render={({ match }) => {
          const page = parseInt(match.params.page, 10);

          return (
            <Categories
              currentIndexPage={page}
              currentPathname="categories"
              pathToCategory="category"
            />
          );
        }}
      />

      <Route exact path="/category/:url" component={Category} />
      <Route exact path="/reviews" component={Reviews} />
      <Route exact path="/blog" component={Blog} />
      <Route exact path="/contacts" component={Contacts} />
      <Route component={AnotherPage} />
    </Switch>
  );
};

export default Routes;

categories
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { actionGetCategoriesItems } from "Store/actions";
import { withRouter } from "react-router-dom";
import { CategoriesList } from "Views";

class Index extends Component {
  componentDidMount() {
    const { getCategoriesItems, currentIndexPage } = this.props;

    getCategoriesItems(currentIndexPage);
  }

  componentDidUpdate(prevProps) {
    if (prevProps.location.pathname !== this.props.location.pathname) {
      if (this.props.currentIndexPage === 1) this.onPageChange(1);
    }
  }

  onPageChange = activePage => {
    const { getCategoriesItems, history, currentPathname } = this.props;

    if (activePage === 1) {
      history.replace(`/${currentPathname}`);
    } else {
      history.replace(`/${currentPathname}/${activePage}`);
    }

    getCategoriesItems(activePage);
  };

  render() {
    const { isLoading } = this.props;

    return (
      <Fragment>
        {!isLoading && (
          <CategoriesList {...this.props} onPageChange={this.onPageChange} />
        )}
      </Fragment>
    );
  }
}

const mapStateToProps = state => {
  return {
    items: state.reducerListCategories.items,
    totalPages: state.reducerListCategories.totalPages,
    isLoading: state.reducerListCategories.isLoading,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    getCategoriesItems: currentIndexPage =>
      actionGetCategoriesItems(dispatch, currentIndexPage),
  };
};

export default withRouter(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(Index)
);
view
import React, { Component } from "react";
import { Grid, Pagination } from "semantic-ui-react";
import { CategoryCard } from "Components";

class View extends Component {
  render() {
    const {
      items,
      totalPages,
      currentIndexPage,
      pathToCategory,
      onPageChange,
    } = this.props;

    return (
      <div className="listcatecories-component">
        <Grid stretched columns={3}>
          {items.map(item => (
            <Grid.Column key={item._id}>
              <CategoryCard item={item} pathToCategory={pathToCategory} />
            </Grid.Column>
          ))}
        </Grid>
        <Grid centered>
          <Grid.Row>
            {totalPages > 1 && (
              <Pagination
                defaultActivePage={currentIndexPage}
                totalPages={totalPages}
                onPageChange={(e, { activePage }) => onPageChange(activePage)}
              />
            )}
          </Grid.Row>
        </Grid>
      </div>
    );
  }
}

export default View;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
Jedi, 2019-02-25
Demidovets @Nik_o_lay

do not quite understand. It would be great to see the code. And you wrote the route using exact ( Example:

<Route exact path="/categories" component={() => {}/>
) ?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question