Reactjs 侧栏中的动态和非动态路由

Reactjs 侧栏中的动态和非动态路由,reactjs,react-router,Reactjs,React Router,我正在开发一个预算应用程序,供我和妻子使用并学习如何应对。我的应用程序有一个侧边栏和一个顶部导航。侧边栏有一个动态构建的帐户列表以及一个显示一些支出报告的主页。选择其中一个帐户将加载事务组件,该组件将呈现每个帐户的事务 单击主页按钮时,主窗格中的事务组件应该替换为我的主页组件,但我还没有弄清楚如何使用react router实现这一点。希望这是有道理的 下面是侧边栏当前的构建方式: import React from 'react'; import axios from 'axios'; im

我正在开发一个预算应用程序,供我和妻子使用并学习如何应对。我的应用程序有一个侧边栏和一个顶部导航。侧边栏有一个动态构建的帐户列表以及一个显示一些支出报告的主页。选择其中一个帐户将加载事务组件,该组件将呈现每个帐户的事务

单击主页按钮时,主窗格中的事务组件应该替换为我的主页组件,但我还没有弄清楚如何使用react router实现这一点。希望这是有道理的

下面是侧边栏当前的构建方式:

import React from 'react';
import axios from 'axios';

import classnames from 'classnames';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faMoneyCheck, faCreditCard, faPiggyBank, faHome } from '@fortawesome/free-solid-svg-icons'

const API = 'http://127.0.0.1:8000/api/accounts/';

class AccountNavigation extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      data: [],
      checkingAccounts: [],
      savingsAccounts: [],
      creditCardAccounts: [],
      selectedAccount: null,
    }
  }

  handleAccountSelect = (event) => {
    // console.log(event)
    this.props.handleAccountSelect(event.target.value)
    this.setState({
      selectedAccount: event.target.value
    })
  }

  componentDidMount() {
    this.setState({
      isLoading: true
    }, () => {
      // console.log(this.state);
    });

    axios.get(API).then(response => {
      this.setState({
        data: response.data,
        checkingAccounts: response.data.checking,
        savingsAccounts: response.data.savings,
        creditCardAccounts: response.data.credit_card,
        isLoading: false,
      });
    });
  }

  render() {
    const {
      checkingAccounts,
      savingsAccounts,
      creditCardAccounts
    } = this.state;

    return (
      <nav className="no-col-padding bg-light col-md-2 sidebar d-none d-md-block">
        <div className="sidebar-sticky">
          <h6 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1">
            <span><FontAwesomeIcon icon={faHome} /> Home</span>
          </h6>
          <h6 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1">
            <span><FontAwesomeIcon icon={faMoneyCheck} /> Checking</span>
          </h6>
          <ul class="nav flex-column">
              { checkingAccounts.map((account) => {
                var btnClass = classnames({
                  btn: true,
                  'btn-link': true,
                  'nav-link': true,
                  'active': this.state.selectedAccount === account.id.toString()
                });

                  return (
                    <li className="nav-item">
                      <button eventKey={account.id} type="button" className={btnClass} onClick={this.handleAccountSelect} value={account.id}>
                        { account.account_name }
                      </button>
                    </li>
                  )
              })}
          </ul>
          <h6 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1">
            <span><FontAwesomeIcon icon={faCreditCard} /> Credit Cards</span>
          </h6>
          <ul className="nav flex-column">
              { creditCardAccounts.map((account) => {
                var btnClass = classnames({
                  btn: true,
                  'btn-link': true,
                  'nav-link': true,
                  'active': this.state.selectedAccount === account.id.toString()
                });

                  return (
                    <li className="nav-item" activeClassName="active">
                      <button eventKey={account.id} type="button" className={btnClass} onClick={this.handleAccountSelect} value={account.id}>
                        { account.account_name }
                      </button>
                    </li>
                  )
              })}
          </ul>
          <h6 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1">
            <span><FontAwesomeIcon icon={faPiggyBank} /> Savings</span>
          </h6>
          <ul className="nav flex-column">
              { savingsAccounts.map((account) => {
                var btnClass = classnames({
                  btn: true,
                  'btn-link': true,
                  'nav-link': true,
                  'active': this.state.selectedAccount === account.id.toString()
                });

                  return (
                    <li className="nav-item" activeClassName="active">
                      <button eventKey={account.id} type="button" className={btnClass} onClick={this.handleAccountSelect} value={account.id}>
                        { account.account_name }
                      </button>
                    </li>
                  )
              })}
          </ul>
        </div>
      </nav>
    )
  };
}

export default AccountNavigation;
还有我的App.js:

import React from 'react';
import AccountNavigation from './components/AccountNavigation';
import Transactions from './components/Transactions';
import TransactionButtons from './components/TransactionButtons';

import Header from './components/Header';

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      selectedAccount: null,
      showTransactionForm: false
    }

    this.handleAccountSelect = this.handleAccountSelect.bind(this);
  }

  handleAccountSelect = (accountId) => {
    // console.log("print handleAccountSelect called")
    // console.log(accountId)
    this.setState({selectedAccount: accountId});
  };

  render() {
    return (
      <div className="App">
        {/* <Header /> */}
        <nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
          <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">Budget Zen</a>
            {/* <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> */}
          <ul class="navbar-nav px-3">
            <li class="nav-item text-nowrap">
              <a class="nav-link" href="#">Sign out</a>
            </li>
          </ul>
        </nav>
        <div className="container-fluid">
          <div className="row">
            <AccountNavigation
              handleAccountSelect = {this.handleAccountSelect} />
            <main role="main" className="col-md-9 ml-sm-auto col-lg-10 px-4">
                <div className="col-10">
                  <Transactions
                    selectedAccount = {this.state.selectedAccount}
                    showTransactionForm = {this.state.showTransactionForm}/>
                </div>
            </main>
          </div>
        </div>
      </div>);
  }
}

export default App;
我看了很多例子,但没有一个是使用react router和共享同一组件的链接的边栏。

对于react router,您需要将ID作为URL参数传入,在您的情况下,假设是accountId,则App.js中的路由配置为:

import React from 'react';
import { BrowserRouter, Router, Link, Switch } from "react-router-dom";
import AccountNavigation from './components/AccountNavigation';
import Transactions from './components/Transactions';
import TransactionButtons from './components/TransactionButtons';

import Header from './components/Header';

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      showTransactionForm: false
    }

  }

  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
            <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">Budget Zen</a>
              {/* <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> */}
            <ul class="navbar-nav px-3">
              <li class="nav-item text-nowrap">
                <a class="nav-link" href="#">Sign out</a>
              </li>
            </ul>
          </nav>
          <div className="container-fluid">
            <div className="row">
              <AccountNavigation
                handleAccountSelect = {this.handleAccountSelect} />
              <main role="main" className="col-md-9 ml-sm-auto col-lg-10 px-4">
                  <div className="col-10">
                    <Switch>
                      <Route path="/home" component={Home} />
                      <Route path="/:accountId" render={(props) => (<Transaction showTransactionForm = {this.state.showTransactionForm} {...props}/>)} />
                    </Switch>
                  </div>
              </main>
            </div>
          </div>
        </div>
     </BrowserRouter> 
     );
  }
}

export default App;
请记住,AccountNavigation不在路线中,您需要将其包装为以接收历史道具:

在事务组件内部,您可以通过以下方式接收所选accountId:


你能详细说明你面临的问题吗?看起来这只是一个主路由,另一个是dynamic/:transactionId。可能我被甩了,因为我目前正在使用处理程序和状态在帐户之间切换,我想为我的主页和将来的页面设置路由。我根本没有实现react路由器。是否可以使用react路由器实现我的帐户交换?这非常有用。非常感谢。
  handleAccountSelect = (event) => {
    this.props.history.push(event.target.value);
    this.setState({
      selectedAccount: event.target.value
    })
  }
export default withRouter(AccountNavigation);
componentDidMount() {
  const { accountId } = this.props.match.params;
}