D
D
Dmitry2019-05-08 18:52:52
React
Dmitry, 2019-05-08 18:52:52

Evaluate a react component for breadcrumbs?

There is a breadcrumbs component. Every time a page is rendered (each page has its own component), the breadcrumbs are completely reloaded, that is, they are inside the component. Is that the right thing to do?
Here is his code

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

To be honest, I want to completely redo them, while I left them as they are. Are there any developments on this topic?
Thank you.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-05-08
@ddimonn8080

In a good way, the breadcrumbs component should receive an array of elements of the form:

const breadCrumbsItems = [
  {
    title: 'Home',
    path: '/',
  },
   {
    title: 'Products',
    path: '/products',
  },
  {
    title: 'Iphone 6s Black',
  },
];

and build breadcrumbs. It's all. This component should not know any implementation details of your application. And even more so, it should not initiate any AJAX requests.
The whole interface:
with drawing an array of elements using map:
<Wrapper>
  {items.map((item, i) => (
    <BreadCrumbsItem
      key={item.path}
      active={i === items.length - 1}
      path={item.path}
    >
      {item.title}
    </BreadCrumbsItem>
  )}
</Wrapper>

or:
<BreadCrumbs>
  <BreadCrumbs.Item path="/">Home</BreadCrumbs.Item>
  <BreadCrumbs.Item path="/products">Products</BreadCrumbs.Item>
  <BreadCrumbs.Item active>Iphone 6S Black</BreadCrumbs.Item>
</BreadCrumbs>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question