简体   繁体   中英

Get query parameters from react-router-dom into a functional component?

I have a router file to which I am passing query parameters to a functional component. I am using react-router-dom how can I get the query parameters in a functional component?

The line in question which sends parameters is

<Route path="/reports/daily-sales-single/:date_from" component={DailySalesSingle} />

Here I am sending a date_from parameter. I have seen various ways but none of them see conclusive in how to do this or seem out of date. Also every tutorial seems to be people using class components.

Router file:

    import * as React from 'react';
import {
    BrowserRouter as Router,
    Route,
    Switch,
} from 'react-router-dom';
import { asyncComponent } from '@hoc/index';
import { useSpring, useTransition, animated } from 'react-spring';
import useRouter from '@hooks/useRouter';

import Error from '@containers/Error/index';

const Home = asyncComponent(() => import(/* webpackChunkName: "js/chunks/home" */ '@containers/home').then(
    module => module.default,
));

const RatesOverview = asyncComponent(() => import(/* webpackChunkName: "js/chunks/ratesoverview" */ '@containers/RatesOverview').then(
    module => module.default,
));

const CreateRate = asyncComponent(() => import(/* webpackChunkName: "js/chunks/createrates" */ '@containers/CreateRates').then(
     module => module.default,
));

const CopyRate = asyncComponent(() => import(/* webpackChunkName: "js/chunks/createrates" */ '@containers/CreateRates/copyRate').then(
     module => module.default,
));

const RateHurdleOverview = asyncComponent(() => import(/* webpackChunkName: "js/chunks/hurdleOverview" */ '@containers/RateHurdleOverview').then(
  module => module.default,
));

const DailySalesSingle = asyncComponent(() => import(/* webpackChunkName: "js/chunks/dailysalessingle" */ '@containers/Reports/DailySalesSingle').then(
    module => module.default,
));

const DailySalesGroup = asyncComponent(() => import(/* webpackChunkName: "js/chunks/dailysalesgroup" */ '@containers/Reports/DailySalesGroup').then(
    module => module.default,
));

const WeeklySalesSingle = asyncComponent(() => import(/* webpackChunkName: "js/chunks/weeklysalessingle" */ '@containers/Reports/WeeklySalesSingle').then(
    module => module.default,
));

const WeeklySalesGroup = asyncComponent(() => import(/* webpackChunkName: "js/chunks/weeklysalesgroup" */ '@containers/Reports/WeeklySalesGroup').then(
    module => module.default,
));

const Settings = asyncComponent(() => import(/* webpackChunkName: "js/chunks/settings" */ '@containers/Settings').then(
    module => module.default,
));

const CreateRateHurdle = asyncComponent(() => import(/* webpackChunkName: "js/chunks/hurdlecreaterate" */ '@components/Forms/CreateRateHurdle').then(
    module => module.default,
));

const RatesGrid = asyncComponent(() => import(/* webpackChunkName: "js/chunks/ratesgrid" */ '@containers/RatesGrid').then(
    module => module.default,
));

const GroupDasboard = asyncComponent(() => import(/* webpackChunkName: "js/chunks/groupdashboard" */ '@containers/Group/Dashboard').then(
  module => module.default,
));

const Routes = () => {
    /* eslint-disable  no-shadow */
    const { location } = useRouter();
    const transitions = useTransition(location, location => location.pathname, {
        from: {
            opacity: 0,
            position: 'absolute',
            width: '100%',
            transform: 'translate3d(-100%, 0, 0)',
        },
        enter: {
            opacity: 1,
            transform: 'translate3d(0, 0, 0,)',
        },
        leave: { opacity: 0, transform: 'translate3d(150%, 0, 0)' },
    });
    /* eslint-enable no-shadow */
    return transitions.map(({ item, key, props }) => (
        <>
        <div className="app-page">
          <animated.div className="app-content" key={key} style={props}>
                <Error />
                <Switch location={item}>
                    <Route exact path="/" component={GroupDasboard} />
                    <Route path="/rates/overview" component={RatesOverview} />
                    <Route path="/rates/create" component={CreateRate} />
                    <Route path="/rates/grid" component={RatesGrid} />
                    <Route path="/rates/copy/:rate_id" component={CopyRate} />
                    <Route path="/rates/hurdle/create" component={CreateRateHurdle} />
                    <Route path="/rates/hurdle" component={RateHurdleOverview} />
                    <Route path="/reports/daily-sales-single/:date_from" component={DailySalesSingle} />
                    <Route path="/reports/daily-sales-group" component={DailySalesGroup} />
                    <Route path="/group/dashboard" component={GroupDasboard} />
                    <Route path="/reports/weekly-sales-single" component={WeeklySalesSingle} />
                    <Route path="/reports/weekly-sales-group" component={WeeklySalesGroup} />
                    { /* <Route path="/settings" component={Settings} /> */}
                </Switch>
          </animated.div>
        </div>
        </>
    ));
};

export default Routes;

Functional Component:

    import * as React from 'react';
import { connect } from 'react-redux';
import * as actions from '@actions/index';

import { QuickSearchMenu, WeeklyQuickSearchMenu } from '@constants/DateLists';
import { SearchBarDatesSchema } from '@constants/Yup/SearchBarDatesSchema.ts';

import { ToggleWithLabel } from '@components/inputs/index';
import PageHeader from '@components/Header/PageHeader';

import {
  Jumbotron,
  Container,
  Row,
} from 'react-bootstrap';

import {
  Formik,
  Form,
  Field,
} from 'formik';

import { log } from 'util';

import Title from './Title';
import SearchBy from './SearchBy';
import QuickSearch from './QuickSearch';
import Dates from './Dates';
import Properties from './Properties';
import DepartmentToggle from './DepartmentToggle';
import DepartmentTitle from './DepartmentTitle';
import RunReport from './RunReport';
import AdvSearch from './AdvSearch';
import AdvSearchToggle from './AdvSearchToggle';
import Options from './Options';

interface StateProps {
  isModalOpen: boolean;
  isSidebarOpen: boolean;
}

interface InitialProps {
  page: any;
  title: any;
  subTitle: string;
  dataLocal: any;
  type: string;
}

interface DispatchProps {
  getAllDepartments: (payload: any) => void;
  getAllPaymentMethods: (payload: any) => void;
}

type Props = InitialProps & StateProps & DispatchProps;

function mapDispatchToProps(dispatch: React.Dispatch<any>): DispatchProps {
  return {
    getAllDepartments: payload => dispatch(actions.Reports.getAllDepartments(payload)),
    getAllPaymentMethods: payload => dispatch(actions.Reports.getAllPaymentMethods(payload)),
  };
}

const Header = ({
  page,
  title,
  subTitle,
  dataLocal,
  getAllDepartments,
  getAllPaymentMethods,
  type,
 }: Props) => {
  const [department, setDepartment] = React.useState({ status: true });
  const [advSearch, setAdvSearch] = React.useState({ status: false });
  const [quickSearchDates, setQuickSearchDates] = React.useState({
    dateName: null,
    fromDate: null,
    toDate: null,
  });
  const [apiDates, setApiDates] = React.useState({
    fromDate: null,
    toDate: null,
  });

  const [netOrGross, setNetOrGross] = React.useState(true);

  const updateQuickSearchDates = () => {
    if (apiDates.fromDate === null && apiDates.toDate === null) {
      const today = new Date();
      setQuickSearchDates({
        dateName: 'Today',
        fromDate: today,
        toDate: today,
      });
    }
  };

  const getQuickSearchMenu = () => ((
  page === 'weekly-sales-single'
  || page === 'weekly-sales-group')
  ? WeeklyQuickSearchMenu
  : QuickSearchMenu);

  const disableComponent = () => ((
  page === 'weekly-sales-single'
  || page === 'weekly-sales-group')
  // eslint-disable-next-line
  ? true
  : false);

  const onChange = (e: MouseEvent | KeyboardEvent) => {
    setNetOrGross(e.target.value);
  };

  return (
    <div className="daily-sales-header">
    <PageHeader title={title} helpPage="help">
        <Container fluid>
          <Formik
            validateOnChange
            initialValues={{}}
            validationSchema={SearchBarDatesSchema}
            onSubmit={(values, { setSubmitting }) => {
              updateQuickSearchDates();
              getAllPaymentMethods({
                type,
                apiDates,
              });
              getAllDepartments({
                type,
                department,
                apiDates,
              });
              setSubmitting(false);
            }}
          >
              {({
                isSubmitting,
                handleSubmit,
              }) => (
              <Form onSubmit={handleSubmit}>
                <Row>
                  {/* { page === 'daily-sale-single' && (
                  <SearchBy
                    colClass="search-by-col"
                    buttonId="search-by-button"
                    buttonLabel="Search by"
                  />
                  )} */}
                  <QuickSearch
                    buttonLabel="Quick Search"
                    eleClass="quick-search"
                    eleIdBtn="quick-search-button"
                    quickSearchMenu={getQuickSearchMenu()}
                    setQuickSearchDates={setQuickSearchDates}
                    getQuickSearchDates={quickSearchDates}
                    disable={disableComponent()}
                  />
                  <Field
                    fromClass="from-date"
                    fromLabel="From"
                    toClass="to-date"
                    toLabel="To"
                    setQuickSearchDates={quickSearchDates}
                    setApiDates={setApiDates}
                    component={Dates}
                    disable={disableComponent()}
                  />
                  { page === 'daily-sale-groups' && (
                  <Properties
                    colClass="search-by-col"
                    buttonId="search-by-button"
                    buttonLabel="Properties"
                  />
                  )}
                  { (page === 'daily-sale-single'
                      || page === 'weekly-sales-single'
                      || page === 'weekly-sales-group') && (
                  <DepartmentToggle
                    buttonOneLabel="Department"
                    buttonTwoLabel="Sub-Department"
                    variantSelected="primary"
                    variantUnSelected="outline-primary"
                    setDepartment={setDepartment}
                    status={department.status}
                    isSubmitting={isSubmitting}
                    disable={disableComponent()}
                  />
                  )}
                  <RunReport
                    buttonLabel="Run Report"
                    isSubmitting={isSubmitting}
                    departmentToggle={department.status}
                    disable={disableComponent()}
                  />
                </Row>
                <AdvSearch
                  advSearchToggle={advSearch.status}
                />
                <Row>
                  <AdvSearchToggle
                    buttonClass="adv-search-btn pull-right"
                    buttonLabel="Advanced Search"
                    setAdvSearch={setAdvSearch}
                    status={advSearch.status}
                  />
                </Row>
              </Form>
            )}
          </Formik>
        </Container>
      <Row>
        <DepartmentTitle
          title="Department"
          departmentToggle={department.status}
          departmentClass="display-title"
        />
        <div className="col-md-auto">
        { (page === 'weekly-sales-single'
          || page === 'weekly-sales-group') && (
        <div className="col-md-auto">
          <ToggleWithLabel
            label="Net / Gross"
            field={{
              onChange,
              value: netOrGross,
              name: 'net_or_gross',
            }}
          />
        </div>
        )}
        </div>
        <Options
          data={dataLocal}
        />
      </Row>
    </PageHeader>
    </div>
  );
};

export default connect(null, mapDispatchToProps)(Header);

I use this way:

const MyComponent = (props) => {

    console.log(props.match.params.id)
}

You need to add in routes:

<Route path="/reports/daily-sales-single/:from?/:to?" component={DailySalesSingle} />

Then in the functional component:

interface RouterProps {
  match: any;
}

type Props = RouterProps;

const functionalComponent = ({
  match,
 }: Props) => {
     console.log(match.params);
 })

I did this:

const MyComponent = (props) => {
    console.log("query",props.location.search)
    }

If you are using functional components and typescript you may use the following to get your router parameters:

In the router:

<Route exact path="/portal/welcome2/:sms" component={Welcome2}></Route>

In the component:

import React, { FC } from 'react';
import { useParams } from 'react-router-dom';

type WelcomeParams = {
  sms: string;
};

const Welcome2: FC = () => {
  const { sms } = useParams<WelcomeParams>();

  return (
    <h1>Welcome! here {sms}</h1>

  );
};

export default Welcome2;
<main>
      <Routes>
      <Route path="/cart/:id" element={<CartScreen />} />
      <Route path="/" element={<HomeScreen />} exact />
      <Route path="/product/:id" element={<ProductScreen />} />
      </Routes>
    </main>

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