Eze25
Eze25

Reputation: 11

I can't change route from Primereact menu

I am using PrimeReact menu to changue routes, the problem that I have is when I run the application, the line "command: this.props.ruta ('Detalle')" run automatically and I can't changue to home. I try to pass parameter to "function handle (route)" for to achieve the change of route but don't work. It don't know if that i did is correct. I hope you can help me. Thanks.

App.js

import './App.css';
import AppMenu from './AppMenu';
import DetalleMeet from './components/detalleMeet.component'
import { MeetList } from './components/meetList.component';
import { Switch, Route, Link } from "react-router-dom";
import { useHistory } from "react-router-dom";

function App() {

  const history = useHistory();

    function handle(ruta) {
      history.push("/" + ruta);
    }

    return (

    <div className="App">

      <AppMenu ruta={handle} />
 
      <div className="container mt-3">

      <Switch>
        <Route exact path={"/meetups"} component={MeetList} />
        <Route exact path={"/detalle"} component={DetalleMeet} />
        <Route exact path={["/", "/home"]} component={MeetList} />
      </Switch>
  
      </div>

    </div>
  );
}

export default App;

AppMenu.js

import "primeicons/primeicons.css";
import 'primereact/resources/themes/saga-blue/theme.css';
import React from 'react';
import 'primeflex/primeflex.css';
import { Menubar } from 'primereact/menubar';
import { InputText } from 'primereact/inputtext';
import 'primereact/resources/primereact.css';
import 'primeflex/primeflex.css';

export default class AppMenu extends React.Component {

    constructor(props) {
        super(props);
        this.items = [
            {
                label: 'Home',
                icon: 'pi pi-fw pi-file',
                command: this.props.ruta('home')
            },
            {
                label: 'Detalle',
                icon: 'pi pi-fw pi-pencil',
                command: this.props.ruta('Detalle')
            },
            {
                label: 'Users',
                icon: 'pi pi-fw pi-user',
            },
            {
                label: 'Events',
                icon: 'pi pi-fw pi-calendar',
            },
            {
                label: 'Quit',
                icon: 'pi pi-fw pi-power-off'
            }
        ];


    }

    render(){

        const start = <img alt="logo" src="showcase/images/logo.png" onError={(e) => e.target.src='https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'} height="40" className="p-mr-2"></img>;
        const end = <InputText placeholder="Search" type="text" />;

        return (

           <div>

                <div>
                    <div className="card">
                        <Menubar model={this.items} start={start} end={start} />
                    </div>
                </div>

            </div>

        );

    }

}

Upvotes: 1

Views: 5483

Answers (3)

Samuel Chan
Samuel Chan

Reputation: 31

Regarding the new version of React-Router and PrimeReact. You can rock it with the useNavigate directly.

import "./MyMenu.scss"
import React from "react";
import { Menubar } from 'primereact/menubar';
import {InputText} from "primereact/inputtext";
import {Button} from "primereact/button";
import {PrimeIcons} from "primereact/api";
import {useNavigate} from "react-router-dom";


const MyMenu = (props) => {
        const navigate = useNavigate();
        const items =  [
            {
                label: 'Home',
                icon: PrimeIcons.HOME,
                command: () => {navigate('/') }
            }
        ];

        let searchAndLogout = <div>
            <InputText placeholder="Search" type="text"/>
            <Button label="Exit" icon="pi pi-power-off"/>
        </div>

        return (
            <div className="my-menu">
                <Menubar model={items} end={searchAndLogout}/>
            </div>
        );
}


export default MyMenu;

Upvotes: 2

Sagar Mishra
Sagar Mishra

Reputation: 31

I have implemented primefaces menubar with react router.

First I have created a navigation items object as described in primefaces documentation.

navigationConfig.js looks like this:

 export const navitems = [
    {
        label: 'Africa',
        icon: 'pi pi-fw pi-user',
        url: '/africa'
    },
    {
        label: 'Europe',
        icon: 'pi pi-fw pi-pencil',
        url: '/europe'
    },
    {
        label: 'Asia',
        icon: 'pi pi-fw pi-th-large',
        items: [
            {
                label: 'Japan',
                url: '/japan'
            },
            {
                label: 'Mongolia',
                url: '/mongolia'
            },
            {
                label: 'Nepal',
                items: [
                    {
                        label: 'Kathmandu',
                        url: '/kathmandu'
                    },
                    {
                        label: 'Pokhara',
                        url: '/pokhara'
                    }
                ]
            }
        ]
    }
]

Then in my navigation component I have created a recursive method that maps each url of menu item into a command method which then calls a history.push() method of useHistory() hook from react-router-dom

Full navigation component looks like this:

import React from 'react';
import * as nav from '../config/navigation';
import { Menubar } from 'primereact/menubar';
import {Button} from 'primereact/button';
import { useHistory } from "react-router-dom";


const Navigation = (props) => {

    const history=useHistory();

    const getMenuObject=(menu)=>{
       
        let menuObj={};

        menuObj.label=menu.label;

        if(menu.items){
           //if the navigation has items property then map each item and call itself again
            menuObj.items=menu.items.map(nestedItem=>{
                return getMenuObject(nestedItem);
            });  
        }

        if(menu.icon){
            menuObj.icon=menu.icon;
        }
        if(menu.url){
            menuObj.command=()=>{
               navigatePage(menu.url);
            }
        }
       
        return menuObj;
    }

    const navigationMenu=nav.navitems.map(menuItem=>{
        return getMenuObject(menuItem);
    })
    
    const navigatePage=(url)=>{
        history.push(url);
    }


    return (
        <Menubar 
        model={navigationMenu}
        end={<Button label="Logout"  onClick={(e)=>props.onLogout(e)} icon="pi pi-power-off"/>}
        />
    );
}

export default Navigation;

Hope it will help whoever is looking for a solution. 😊🙏

Upvotes: 1

Eze25
Eze25

Reputation: 11

I could fix it. The problem was in how I was calling the function in command. I only had to changue "command: this.props.ruta('home')" for "command: () => {this.props.ruta('/home')}". I hope it helps someone. Next the new code.

import "primeicons/primeicons.css";
import 'primereact/resources/themes/saga-blue/theme.css';
import React from 'react';
import 'primeflex/primeflex.css';
import { Menubar } from 'primereact/menubar';
import { InputText } from 'primereact/inputtext';


import 'primereact/resources/primereact.css';
import 'primeflex/primeflex.css';


export default class AppMenu extends React.Component {

    constructor(props) {
        super(props);


        this.home = this.home.bind(this);
        this.items = [
            {
                label: 'Home',
                icon: 'pi pi-fw pi-file',
                command: () => {this.props.ruta('/home')}
            },
            {
                label: 'Detalle',
                icon: 'pi pi-fw pi-pencil',
                command: () => {this.props.ruta('/detalle')}
            },
            {
                label: 'Users',
                icon: 'pi pi-fw pi-user',
            },
            {
                label: 'Events',
                icon: 'pi pi-fw pi-calendar',
            },
            {
                label: 'Quit',
                icon: 'pi pi-fw pi-power-off'
            }
        ];


    }


    home() {
        this.props.ruta('/home')
    }

    detalle() {
        this.props.ruta('/detalle')
    }


    render(){

        const start = <img alt="logo" src="showcase/images/logo.png" onError= 
{(e) => e.target.src='https://www.primefaces.org/wp- 
content/uploads/2020/05/placeholder.png'} height="40" className="p-mr-2"></img>;
        const end = <InputText placeholder="Search" type="text" />;

        return (

        <div>

                <div>
                    <div className="card">
                        <Menubar model={this.items} start={start} end={start} />
                    </div>
                </div>

            </div>

        );

    }

}

Upvotes: 0

Related Questions