ddimonn8080
@ddimonn8080

Оцените react компонент для хлебных крошек?

Есть компонент breadcrumbs. Каждый раз когда происходит рендер страницы(для каждой страницы свой компонент) хлебные крошки полностью перегружаются, то есть он находятся внутри компонента. Так правильно делать?
Вот его код
components/pages/DoyouknowPage/DoyouknowPage.jsx

import React, { Component } from 'react';
import doyouknowPageMagnificPopupInit from "../DoyouknowPage/doyouknowPageMagnificPopupInit";
import GridList from "../commons/grid/GridList";
import Breadcrumbs from '../../../helpers/breadcrumbs';

class DoyouknowPage extends Component {
    componentDidMount(){
        const {setAllDoyouknows} = this.props;
        setAllDoyouknows();
    }

    render(){
        const {isDoyouknowsReady, isDoyouknowsLoading, doyouknowsErrors, doyouknowsList, doyouknowsAttachment} = this.props;
        const matchPath = this.props.match.path;

        return (
            <React.Fragment>
                <div className="container">
                    <div className="row">
                        <div className="col-xs-12">
                            <Breadcrumbs />
                        </div>
                    </div>
                </div>

                <GridList
                    isLoading={isDoyouknowsLoading}
                    isReady={isDoyouknowsReady}
                    errors={doyouknowsErrors}
                    list={doyouknowsList}
                    attachment={doyouknowsAttachment}
                    matchPath={matchPath}
                    noMessage='Новостей пока нет.'
                    popupInit={doyouknowPageMagnificPopupInit}
                />
            </React.Fragment>
        );
    }
}

export default DoyouknowPage;

helpers/breadcrumbs.js

import React, {Component} from 'react';
import {Route, Link} from 'react-router-dom';
import {getCategoryProductRelationsByProductSlug} from '../helpers/getCategoryProductRelations';

class Breadcrumbs extends Component {

    componentDidMount(){
        axios.get('/api/pages').then(({data}) => {
            const slugsPagesNames = {};
            data.forEach((elem, index) => {
                var slugEl = elem.slug;
                slugsPagesNames[slugEl] = elem.title;
            });

            this.setState({
                slugsPagesNames: slugsPagesNames,
            });
        });

        axios.get('/api/products').then(({data}) => {
            const slugsProductsNames = {};
            data.productsList.forEach((elem, index) => {
                var slugEl = elem.slug;
                slugsProductsNames[slugEl] = elem.title;
            });

            const slugsProductCats = getCategoryProductRelationsByProductSlug(data.categoriesRelationship);

            this.setState({
                slugsProductsNames: slugsProductsNames,
                slugsProductCats: slugsProductCats,
            });
        });
    }

    render(){
        return (
            <BreadcrumbsComp
                slugsPagesNames={this.state && this.state.slugsPagesNames}
                slugsProductsNames={this.state && this.state.slugsProductsNames}
                slugsProductCats={this.state && this.state.slugsProductCats}
            />
        );
    }
}

export default Breadcrumbs;

export const BreadcrumbsComp = props => {

    const allSlugsNames = {...props.slugsPagesNames, ...props.slugsProductsNames};
    const productCatsSlugNames = props.slugsProductCats;

    return (
        <Route
            path="*"
            render={ props => {
                    let parts = props.location.pathname.split("/");
                    
                    const place = parts[parts.length - 1];

                    parts = parts.slice(1, parts.length - 1);

                    return (
                        <div className="kama_breadcrumbs">
                            {<Link to={'/'}>Главная</Link>}
                            {
                                parts.map((part, partIndex, parts) => {
                                    const path = ['', ...parts.slice(0, partIndex+1)].join("/");
                                    return (
                                        <i key={part}>
                                            {<span className="kb_sep"> / </span>}
                                            <Link key={path} to={path} >{allSlugsNames && allSlugsNames[part]}</Link>
                                        </i>
                                    );
                                })
                            }
                            <span className="kb_sep"> / </span>
                            {/* START: if has category show category name*/}
                            <span>{(productCatsSlugNames instanceof Array) && (productCatsSlugNames[place]) && productCatsSlugNames[place][0]}</span>
                            {(productCatsSlugNames instanceof Array) && (productCatsSlugNames[place]) && <span className="kb_sep"> / </span>}
                            {/* END: if has category show category name*/}
                            {allSlugsNames && allSlugsNames[place]}
                        </div>
                    );
                }
            }
        />);
};


Если честно, хочу их полностью переделать, пока оставил как есть. Есть какие-то наработки на эту тему?

Спасибо.
  • Вопрос задан
  • 1819 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
По-хорошему компонент breadcrumbs должен получать массив элементов вида:
const breadCrumbsItems = [
  {
    title: 'Home',
    path: '/',
  },
   {
    title: 'Products',
    path: '/products',
  },
  {
    title: 'Iphone 6s Black',
  },
];

и строить хлебыные крошки. Это все. Никаких деталей реализации вашего приложения этот компонент знать не должен. И уж тем более не должен инициировать никаких AJAX запросов.

Весь интерфейс:
<BreadCrumbs items={breadCrumbsItems} />
c отрисовкой массива элементов с помощью map:
<Wrapper>
  {items.map((item, i) => (
    <BreadCrumbsItem
      key={item.path}
      active={i === items.length - 1}
      path={item.path}
    >
      {item.title}
    </BreadCrumbsItem>
  )}
</Wrapper>


или:
<BreadCrumbs>
  <BreadCrumbs.Item path="/">Home</BreadCrumbs.Item>
  <BreadCrumbs.Item path="/products">Products</BreadCrumbs.Item>
  <BreadCrumbs.Item active>Iphone 6S Black</BreadCrumbs.Item>
</BreadCrumbs>
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
27 нояб. 2024, в 18:19
2000 руб./за проект
27 нояб. 2024, в 17:41
2000 руб./за проект
27 нояб. 2024, в 17:26
1 руб./за проект