Задать вопрос
Nik_o_lay
@Nik_o_lay
Изучаю фронтенд

Почему Route срабатывает два раза?

Использую BrowserRouter. Есть меню с Link-ами. При клике на один из них один раз срабатывает соответствующий Route. Есть пункт в меню Категории, где выводятся категории товаров, так как их очень много, то пришлось использовать пагинацию, поэтому есть два роута, один который срабатывает при клике в меню ("/categories"), а второй при клике на пункт в пагинации ("/categories/:page").

Если мы кликнем на Категории, то один раз сработает "/categories". Потом перейдет, например, на 2ю страницу "/categories/2" сработает один раз соответствующий роут "/categories/:page". Но вот если мы теперь снова кликнем на Категории, то роут "/categories" срабатывает уже два раза. Почему?

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;
  • Вопрос задан
  • 235 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
@PHPjedi
не совсем понял. Было бы здорово увидеть код. А ты роут написал с использованием exact ( Пример:
<Route exact path="/categories" component={() => {}/>
)
?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы