将车辆类型参数传递给 API 时出现问题

问题描述 投票:0回答:1

我在将车辆类型作为参数传递给 React 应用程序中的 API 时遇到问题。当尝试将变量“vehicle”传递到 API 端点时,就会出现问题;它收到 undefined 而不是“carros”、“motos”或“caminhoes”。

这是我项目中的相关代码:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { Brand } from '../pages/VehicleBrand'

const api = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://parallelum.com.br/fipe/api/v1',
  }),
  endpoints: (builder) => ({
    getBrand: builder.query<Brand[], string>({
      query: (vehicle) => `${vehicle}/marcas`,
    }),
  }),
})

export const { useGetBrandQuery } = api

export default api
import { PayloadAction, createSlice } from '@reduxjs/toolkit'

export type vehicleState = {
  vehicle: string
}

const initialState: vehicleState = {
  vehicle: 'carros',
}

const vehicleSlice = createSlice({
  name: 'vehicle',
  initialState,
  reducers: {
    change: (state, action: PayloadAction<string>) => {
      state.vehicle = action.payload
    },
  },
})

export const { change } = vehicleSlice.actions

export default vehicleSlice.reducer
import { useParams } from 'react-router-dom'
import MainBox from '../../components/MainBox'
import { useGetBrandQuery } from '../../services/api'

export type Brand = {
  codigo: string
  nome: string
}

type VehicleParams = {
  vehicle: string
}

const VehicleBrand = () => {
  const { vehicle } = useParams() as VehicleParams
  const { data: brand } = useGetBrandQuery(vehicle!)

  return (
    <div className="container">
      <MainBox
        children="Selecione a marca do veículo"
        to="/VehicleModel"
        selectIsVisible={true}
        btnChildren="Buscar"
        resultIsVisible={false}
        brand={brand}
      />
    </div>
  )
}

export default VehicleBrand
import { configureStore } from '@reduxjs/toolkit'
import vehicleSlice from './reducers/vehicle'
import api from '../services/api'

export const store = configureStore({
  reducer: {
    vehicle: vehicleSlice,
    [api.reducerPath]: api.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(api.middleware),
})

export type RootState = ReturnType<typeof store.getState>

export type AppDispatch = typeof store.dispatch
import { useDispatch } from 'react-redux'
import * as S from './styles'
import { change } from '../../store/reducers/vehicle'

const Header = () => {
  const dispatch = useDispatch()

  const handleChangeVehicle = (vehicle: string) => {
    dispatch(change(vehicle))
  }

  return (
    <S.HeaderDiv>
      <S.Container className="container">
        <S.Title to="/">ConsultaFipe</S.Title>
        <nav>
          <ul>
            <S.NavLink onClick={() => handleChangeVehicle('carros')}>
              Carros
            </S.NavLink>
            <S.NavLink onClick={() => handleChangeVehicle('motos')}>
              Motos
            </S.NavLink>
            <S.NavLink onClick={() => handleChangeVehicle('caminhoes')}>
              Caminhões
            </S.NavLink>
          </ul>
        </nav>
      </S.Container>
    </S.HeaderDiv>
  )
}

export default Header

我已尝试调试该问题,但未能找到解决方案。任何见解或建议将不胜感激。

我需要在 api 查询的 fetch 中读取“vehicle”的值。 “GET”将像这样完成:“GET:https://parallelum.com.br/fipe/api/v1/carros/marcas”,其中值为“car”的将收到车辆的值。

import { Brand } from '../pages/VehicleBrand'

const api = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://parallelum.com.br/fipe/api/v1',
  }),
  endpoints: (builder) => ({
    getBrand: builder.query<Brand[], string>({
      query: (vehicle) => `${vehicle}/marcas`,
    }),
  }),
})

export const { useGetBrandQuery } = api

export default api

控制台返回此错误:VM8:6 获取 https://parallelum.com.br/fipe/api/v1/undefined/marcas 400(错误请求)

这是routes.tsx文件:

import { Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import VehicleModel from './pages/VehicleModel'
import VehicleYear from './pages/VehicleYear'
import VehicleBrand from './pages/VehicleBrand'
import VehicleInfo from './pages/VehicleInfo'

const PagesRouter = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/VehicleBrand" element={<VehicleBrand />} />
      <Route path="/VehicleModel" element={<VehicleModel />} />
      <Route path="/VehicleYear" element={<VehicleYear />} />
      <Route path="/VehicleInfo" element={<VehicleInfo />} />
    </Routes>
  )
}

export default PagesRouter
reactjs typescript react-router-dom redux-toolkit rtk-query
1个回答
0
投票

问题

您的 Redux 存储中似乎有导航项设置了

vehicle
值,例如
state.vehicle.vehicle
同时
VehicleBrand
组件期望从路由参数中读取
vehicle
值。

问题是没有任何路由提供任何路由参数,并且

VehicleBrand
不会从状态读取当前
vehicle
值。

解决方案

导航至路线参数并从中读取
vehicle

更新路线定义以包含

vehicle
路径参数。

const PagesRouter = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route
        path="/VehicleBrand/:vehicle" // <-- add path parameter
        element={<VehicleBrand />}
      />
      <Route path="/VehicleModel" element={<VehicleModel />} />
      <Route path="/VehicleYear" element={<VehicleYear />} />
      <Route path="/VehicleInfo" element={<VehicleInfo />} />
    </Routes>
  );
};

更新导航以在目标路径中包含车辆值。

const Header = () => {
  const dispatch = useDispatch();

  const handleChangeVehicle = (vehicle: string) => {
    dispatch(change(vehicle));
  };

  return (
    <S.HeaderDiv>
      <S.Container className="container">
        <S.Title to="/">ConsultaFipe</S.Title>
        <nav>
          <ul>
            <S.NavLink
              to="/VehicleBrand/carros"
              onClick={() => handleChangeVehicle('carros')}
            >
              Carros
            </S.NavLink>
            <S.NavLink
              to="/VehicleBrand/motos"
              onClick={() => handleChangeVehicle('motos')}
            >
              Motos
            </S.NavLink>
            <S.NavLink
              to="/VehicleBrand/caminhoes"
              onClick={() => handleChangeVehicle('caminhoes')}
            >
              Caminhões
            </S.NavLink>
          </ul>
        </nav>
      </S.Container>
    </S.HeaderDiv>
  );
};

更新

VehicleBrand
以在
vehicle
参数值为 false 时跳过查询。

const VehicleBrand = () => {
  const { vehicle } = useParams() as VehicleParams;
  const { data: brand } = useGetBrandQuery(vehicle, { skip: !vehicle });

  return (
    <div className="container">
      <MainBox
        children="Selecione a marca do veículo"
        to="/VehicleModel"
        selectIsVisible={true}
        btnChildren="Buscar"
        resultIsVisible={false}
        brand={brand}
      />
    </div>
  );
};

从状态
读取
vehicle

从状态中选择

vehicle
值。

const VehicleBrand = () => {
  const { vehicle } = useSelector((state: AppState) => state.vehicle);
  const { data: brand } = useGetBrandQuery(vehicle, { skip: !vehicle });

  return (
    <div className="container">
      <MainBox
        children="Selecione a marca do veículo"
        to="/VehicleModel"
        selectIsVisible={true}
        btnChildren="Buscar"
        resultIsVisible={false}
        brand={brand}
      />
    </div>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.