简体   繁体   中英

Create routes on dynamic menu bar in react js

I want to implement the navigation on menu bar which I am fetching from api. For eg on home page I have four menus like menu1 menu2 menu3 menu4 which displays always. On click on these menus i want to fetch products related to them.

I have read about nested routes in React js but unable to implement that.

Dynamic menu bar of categories:

import React from 'react';
import './style.css';
import {Link} from 'react-router-dom';
import Api from '../../Api';

class TopMenu extends React.Component {
    state = {
        categories : []
    }

    componentDidMount(){
        Api.get(`categories`).then(
            response => {
                this.setState({categories: response.data});
            });
    };

    render(){
        return (
            <div className="menu">
                {this.state.categories.map(category => (
                    <Link to={"/category/" + category.name} key={category.id} className="menu-item"><span>{category.name}</span></Link>
                ))}
            </div>
        );
    }
};

export default TopMenu;

My Routes file:

import React from 'react';
import {Switch, Route} from 'react-router-dom';
import CategoryProducts from './CategoryProducts';
import Home from './Home';

const Routes = () => {
    return(
        <Switch>
            <Route path='/' exact component={Home} />
            <Route path='/category/:name' component={CategoryProducts} />
        </Switch>
    );
};

export default Routes;

The click on Category will just change the browser url, not the page.

CategoryProducts.ja

import React from 'react';
import Products from './Products';

class CategoryProducts extends React.Component {
    render(){
        return (
            <div className="content-wrapper">
                <div className="menu-left">
                    <Products/>
                </div>
            </div>
        );
    }
}

export default CategoryProducts;

Products.js

import React,{useState, useEffect} from 'react';
import Api from './Api'
import Card from './components/Card';

class Products extends React.Component {
    state = {
        categories : []
    }

    componentDidMount(){
        let categoryName = this.props.match ? this.props.match.params.name : 'Veg Pizza';
        Api.get(`category/${categoryName}`).then(
            response => {
                this.setState({products: response.data});
            });
    };


    render(){
        return (
            <div>
                <div className="ref">
                    <div className="menu-hr"></div>
                    <div className="menu-cat">
                        <div className="menu-catname ">BESTSELLERS</div>
                    </div>
                </div>
                <div className="card-container">
                    <div className="all-cards" data-label="Bestsellers">
                        <Card />
                    </div>
                </div>
            </div>
        );
    }
};

export default Products;

Your Products component is not mounting again and again, because this renders on all possible categories. Therefore In order to fetch data for different categories, you might have to use componentDidUpdate lifecycle method.

 import React,{useState, useEffect} from 'react'; import Api from './Api' import Card from './components/Card'; class Products extends React.Component { state = { categories: [] } componentDidMount(){ let categoryName = this.props.match? this.props.match.params.name: 'Veg Pizza'; Api.get(`category/${categoryName}`).then( response => { this.setState({products: response.data}); }); }; componentDidUpdate(prevProps, prevState){ if(prevProps.match.params.name.== this.props.match.params.name){ Api.get(`category/${categoryName}`).then( response => { this:setState({products. response;data}); }); } } render(){ return ( <div> <div className="ref"> <div className="menu-hr"></div> <div className="menu-cat"> <div className="menu-catname ">BESTSELLERS</div> </div> </div> <div className="card-container"> <div className="all-cards" data-label="Bestsellers"> <Card /> </div> </div> </div> ); } }; export default Products;

If you want to force rerenders anyway and componentDidUpdate doesnt works for you, you can cause force rerender using key prop

 import React from 'react'; import Products from './Products'; class CategoryProducts extends React.Component { render(){ return ( <div className="content-wrapper"> <div className="menu-left"> <Products key={this.props.match.params.name}/> </div> </div> ); } } export default CategoryProducts;

Please let me know if ut didnt solve your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM