React & Material UI - Как удалить навигационные кнопки / ссылки на основе маршрутов? - PullRequest
1 голос
/ 03 ноября 2019

Приведенный ниже код является основной записью app.js приложения React и включает в себя конечные точки маршрутизаторов.

Ниже кода app.js указан код компонента Nav (навигации). Я хочу знать, как структурировать этот код так, чтобы при переходе пользователя по определенному маршруту соответствующая ссылка в Nav удалялась. Другими словами, если пользователь находится на localhost: 3000 / calendar, вкладка со словом «calendar» не должна появляться в компоненте Nav.

Я мог бы проанализировать конечные точки и сделать это с помощью множества уродливых условных выражений, которыерендеринг другого кода Nav на основе проанализированных конечных точек - но я думаю, что есть более простой способ, который я не вижу, чтобы делать то, что я хочу.

Спасибо.

App.js

function App(){

    ...code

    function redirectToClientsList(){
        window.location.href = "/";
    }


    function redirectToCalendar(){
        window.location.href = "/calendar";
    }




    return (
       <div className="App">
                <MuiPickersUtilsProvider utils={MomentUtils}>

                    <Nav redirectToClientsList = {redirectToClientsList} redirectToCalendar={redirectToCalendar} />

                    <BrowserRouter>
                        <div>
                            <Switch>
                                <Route exact={true} path="/" component={Landing} />
                                <Route exact={true} path="/test" component={Test} />
                                <Route exact={true} path="/client/:id/client-name/:client/workflows" component={Workflows} />
                                <Route exact={true} path="/calendar" component={Calendar} />
                                <Redirect from="/*" to="/" />
                            </Switch>
                        </div>
                    </BrowserRouter>
                </MuiPickersUtilsProvider>
        </div>
    );

}

export default App;

Nav компонент.

function Navbar(props){

    const {classes} = props;

    return (


          <AppBar className={classes.bgColor} >


            <Toolbar>

                  <Button color="inherit" onClick ={props.redirectToClientsList}>Clients</Button> 
                  <Button color="inherit" onClick ={props.redirectToCalendar}>Calendar</Button>
                  <Button className={classes.saveDataButton} style={{float:"right"}} color="inherit">SAVE</Button>


            </Toolbar>

          </AppBar>



    )
}

Navbar.propTypes = {
    classes: PropTypes.object.isRequired,
};

const styles = theme => (navbarStyle(theme));
export default withStyles(styles)(Navbar);

1 Ответ

0 голосов
/ 03 ноября 2019

Вы можете использовать withRouter, предоставляемый пакетом react-router-4.

Вот пример использования withRouter


Вы можете получитьдоступ к свойствам history объекта и ближайшему совпадению <Route> через компонент withRouter высшего порядка высшего порядка. withRouter будет передавать обновленные match, location и history реквизиты в обернутый компонент всякий раз, когда он рендерится.

import React, { Component } from "react";
import { withRouter } from "react-router";

// A simple component that shows the pathname of the current location

class ShowTheLocation extends Component {
  render() {
    const { match, location, history } = this.props;

    return <div>You are now at {location.pathname}</div>;
  }
}

// Create a new component that is "connected" to the router  
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);

После получения доступа к объекту current location aka route вы можете сделать простой if check, чтобы определить, какие кнопки должны отображаться на этом конкретном route. Я хотел бы создать вспомогательную функцию, которая должна определить именно это, поместить ее в жизненный цикл componentDidMount или эквивалентный хук useEffect (если вы выберете такой подход) `, сохранить результат в состояние и, наконец, выполнить проверку if ив зависимости от результатов, показать / скрыть кнопки


Важное примечание:
withRouter не подписывается на location изменения, такие как React-Redux s connect делает для изменений состояния. Вместо этого повторные визуализации после изменения местоположения распространяются из компонента <Router>. Это означает, что withRouter не выполняет повторную визуализацию при переходах маршрута , если только его родительский компонент не выполняет повторную визуализацию.


Вы можете заключить компонент app.js в withRouter HOC и получите необходимые реквизиты в вашем Nav.js компоненте

// ....
<div className="App">
            <MuiPickersUtilsProvider utils={MomentUtils}>
                <BrowserRouter>
                    <div>
                      <Nav redirectToClientsList = {redirectToClientsList} redirectToCalendar={redirectToCalendar} />
                        <Switch>
                            <Route exact path="/" component={Landing} />
                            <Route exact path="/test" component={Test} />
                            <Route exact path="/client/:id/client-name/:client/workflows" component={Workflows} />
                            <Route exact path="/calendar" component={Calendar} />
                            <Redirect from="/*" to="/" />
                        </Switch>
                    </div>
                </BrowserRouter>
            </MuiPickersUtilsProvider>
    </div>

// LET'S NOW WRAP OUR App.js COMPONENT WITH THE withRouter HOC - [don't forget to import it first] :)
export default withRouter(App);

Nav.js

function Navbar(props){

    const {classes} = props;

      // We're interested in the current path,
     // so, we'll destructure it from the location property    
    const { pathname } = props.location;

    return ( 
          <AppBar className={classes.bgColor} >
            <Toolbar>

             // Here we're going to do our check
             {pathname !== "calendar" ?
                  <Button color="inherit" onClick ={props.redirectToCalendar}>Calendar</Button> : null}

                   <Button color="inherit" onClick ={props.redirectToClientsList}>Clients</Button> 

                  <Button className={classes.saveDataButton} style={{float:"right"}} color="inherit">SAVE</Button>

            </Toolbar>
          </AppBar>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...