【问题标题】:How do I handle multiple query params in javascript?如何在 javascript 中处理多个查询参数?
【发布时间】:2021-11-28 17:11:07
【问题描述】:

我有一个 react 应用程序,我正在尝试使用表格组件。

这个表格组件有多种过滤表格的方法,我希望能够使用这些过滤器更新 URL,这样当我离开并返回时,表格可以从 url 参数中读取并让表格做出反应相应地。

我能够让我的桌子已经做这样的事情,但是当使用多个参数时,我有点迷茫。 我的问题是使用 history.replace 或 history.push` 会覆盖以前的参数,然后更新它们只会在我想简单替换它们时追加更多参数

这是我已经完成的工作:

const useQueryParams = () => {
  const params = new URLSearchParams(useLocation().search);
  const startingAfter = params.get('startingAfter');
  const endingBefore = params.get('endingBefore');
  const status = params.get('status');

  return { params, startingAfter, endingBefore, status };
}

export const MyComponent = () => {
  const history = useHistory();
  const location = useLocation();
  const { params, startingAfter, endingBefore, status } = useQueryParams();
  const [statusFilter, setStatusFilter] = useState<IStatus | string>(
    Status.Pending
  );
  const [dateFilter, setDateFilter] = useState<{
    appointmentStartingAfter?: string;
    appointmentEndingBefore?: string;
  }>({
    appointmentStartingAfter: undefined,
    appointmentEndingBefore: undefined,
  });

  useEffect(() => {
    if (startingAfter || endingBefore) {
      setDateFilter({
        appointmentStartingAfter: moment(startingAfter).toISOString() || undefined,
        appointmentEndingBefore: moment(endingBefore).toISOString() || undefined,
      });
    }

    if (status) {
      setStatusFilter(status);
    }
  }, [startingAfter, endingBefore, status]);

  // ......

  const handleDateChange = (momentDateRange) => {
    const startingAfter = momentDateRange[0].subtract(1, 'day');
    const endingBefore = momentDateRange[1].add(1, 'day');

    history.replace({
      search: `startingAfter=${startingAfter.format('YYYY-MM-DD')}&endingBefore=${endingBefore.format('YYYY-MM-DD')}`,
    });

    setDateFilter({
      appointmentStartingAfter: startingAfter.toISOString() || undefined,
      appointmentEndingBefore: endingBefore.toISOString() || undefined,
    });
  };

  const handleStatusFilter = (value: string) => {
    history.replace({
      search: `status=${value || 'ALL_DOCUMENTS'}`,
    });

    setStatusFilter(value);
  };

  return (
    <>
      // ......
      <DatePicker.RangePicker defaultValue={initialDates} style={{ marginRight: 20 }} onChange={handleDateChange} />
      <CareDocumentStatusFilter value={statusFilter} onChange={handleStatusFilter} />
    </>
  );
}

我能够让这些 URL 与 history.replacehistory.push 一起使用,但是当我希望它们保持持久性时,它们会相互覆盖。

例如,

    history.replace({
      search: `startingAfter=${startingAfter.format('YYYY-MM-DD')}&endingBefore=${endingBefore.format('YYYY-MM-DD')}`,
    });
    // localhost:3000/xyz?startingAfter=2021-08-06&endingBefore=2021-08-19

然后在handleStatusFilter

    history.replace({
      search: `status=${value || 'ALL_DOCUMENTS'}`,
    });
    // localhost:3000/xyz?status=CREATED

在上面的示例中,status 将在预期 URL 应类似于以下内容时覆盖参数:

localhost:3000/xyz?startingAfter=2021-08-06&endingBefore=2021-08-19&status=CREATED

在我的不同尝试中,当我想更新它时,而不是更改参数,参数似乎只是附加更多,最终看起来像这样:

localhost:3000/xyz?startingAfter=2021-08-06&endingBefore=2021-08-19&status=CREATED?startingAfter=xxxx&endingBefore=yyyy&status=zzzz

我也有react-router-dom 可供使用。

【问题讨论】:

    标签: javascript reactjs react-router react-router-dom


    【解决方案1】:

    所以我很有趣地stumbled upon this answer,它似乎解决了我的问题。我相信使用URLSearchParams.set 是这里的关键。我并不完全了解内部工作原理......但它有效!这是我的解决方案:

      const handleDateChange = (momentDateRange) => {
        const startingAfter = momentDateRange[0].subtract(1, 'day');
        const endingBefore = momentDateRange[1].add(1, 'day');
    
        // This was important!
        params.set('startingAfter', startingAfter.format('YYYY-MM-DD'));
        params.set('endingBefore', endingBefore.format('YYYY-MM-DD'));
    
        history.push({
          // and so was this ...?
          pathname: location.pathname,
          search: params.toString(),
        });
    
        setDateFilter({
          appointmentStartingAfter: startingAfter.toISOString() || undefined,
          appointmentEndingBefore: endingBefore.toISOString() || undefined,
        });
      };
    
      const handleStatusFilter = (value: string) => {
        // This was important!
        params.set('status', value || 'ALL_DOCUMENTS');
    
        history.push({
          // ... and so was this?
          pathname: location.pathname,
          search: params.toString(),
        })
    
        setStatusFilter(value);
      };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 2017-08-21
      • 2016-05-31
      • 2011-01-14
      • 1970-01-01
      • 2011-06-22
      相关资源
      最近更新 更多