You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript/React中生成带括号格式的URL查询参数?

问题:生成指定格式的orderBy请求参数URL

希望生成如下格式的URL:

{{url}}/invoices?orderBy[created_at]=asc&orderBy[reference_number]=asc

但当前在React项目的invoiceApi.js中直接传递orderBy对象作为请求参数时,无法得到该格式。以下是相关代码文件:

invoiceApi.js

import api from '@/api/api';
import { useMutation, useQuery } from '@tanstack/react-query';

const invoiceUrl = `/invoices`;

export const fetchInvoices = (
  {
    pageNumber,
    pageSize,
    search = '',
    orderBy = { created_at: 'asc', reference_number: 'asc' },
  },
  config
) => {
  const params = {
    page: pageNumber + 1,
    size: pageSize,
    search,
    orderBy, // 直接传递对象无法生成目标格式
  };
  return api.get(invoiceUrl, {
    ...config,
    params: {
      ...config.params,
      ...params,
    },
  });
};

export const useFetchInvoicesQuery = (data) => {
  const { pageNumber, pageSize, search } = data;
  return useQuery({
    queryKey: ['invoices', pageNumber, pageSize, search],
    queryFn: () => fetchInvoices(data),
  });
};

InvoiceAutocomplete.js

import { useFetchInvoicesQuery } from '@/api/invoiceApi';
import { useDebounceValue } from '@/hooks/useDebounceValue';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import PropTypes from 'prop-types';
import React, { useState } from 'react';

export default function renderInvoiceAutocomplete(params) {
  return <InvoiceAutocomplete {...params} />;
}

const InvoiceAutocomplete = ({
  field,
  form: { touched, errors, setFieldValue },
  ...props
}) => {
  const [inputValue, setInputValue] = useState('');
  const debouncedInputValue = useDebounceValue(inputValue, 500);

  const { data: response, isLoading } = useFetchInvoicesQuery({
    pageNumber: 0,
    pageSize: 50,
    search: debouncedInputValue,
  });

  const handleChange = (_, newValue, reason) => {
    if (reason === 'clear') {
      setFieldValue(field.name, { id: '', invoice_number: '' });
      setFieldValue('total_amount', undefined);
      return;
    }
    setFieldValue(field.name, newValue);
    setFieldValue('total_amount', newValue?.amount);
  };

  const handleInputChange = (_, newInputValue) => {
    setInputValue(newInputValue);
  };

  return (
    <Autocomplete
      {...field}
      getOptionLabel={(option) =>
        typeof option === 'string' ? option : option?.invoice_number || ''
      }
      renderOption={(props, option) => {
        return (
          <li {...props} key={option.id}>
            {option?.invoice_number}
          </li>
        );
      }}
      filterOptions={(x) => x}
      options={response?.data?.data || []}
      autoComplete
      includeInputInList
      filterSelectedOptions
      noOptionsText={isLoading ? 'Loading...' : 'No data'}
      onChange={handleChange}
      inputValue={inputValue}
      onInputChange={handleInputChange}
      renderInput={(params) => (
        <TextField
          {...params}
          {...props}
          error={touched[field.name] && errors[field.name] ? true : false}
          helperText={
            touched[field.name] &&
            errors[field.name] &&
            String(errors[field.name].id)
          }
        />
      )}
      fullWidth
    />
  );
};

InvoiceAutocomplete.propTypes = {
  field: PropTypes.object.isRequired,
  form: PropTypes.object.isRequired,
};

解决方案

问题出在HTTP客户端(如axios)默认会将嵌套对象序列化为数组格式,无法生成目标的扁平参数结构。需要手动将orderBy对象转换为orderBy[字段名]: 值的键值对格式:

修改invoiceApi.js中的fetchInvoices函数:

export const fetchInvoices = (
  {
    pageNumber,
    pageSize,
    search = '',
    orderBy = { created_at: 'asc', reference_number: 'asc' },
  },
  config
) => {
  // 将orderBy对象转换为目标格式的参数
  const orderByParams = Object.entries(orderBy).reduce((acc, [key, value]) => {
    acc[`orderBy[${key}]`] = value;
    return acc;
  }, {});

  const params = {
    page: pageNumber + 1,
    size: pageSize,
    search,
    ...orderByParams, // 展开转换后的参数
  };
  return api.get(invoiceUrl, {
    ...config,
    params: {
      ...config.params,
      ...params,
    },
  });
};

核心逻辑说明

  • 用Object.entries遍历orderBy对象的每个键值对
  • 通过reduce方法将每个键值对映射为orderBy[字段名]: 值的格式
  • 把转换后的参数展开到params中,替代原来直接传递的orderBy对象

修改后,请求URL会自动生成为你需要的orderBy[created_at]=asc&orderBy[reference_number]=asc格式。

内容的提问来源于stack exchange,提问作者Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:04:56