简体   繁体   中英

Make two consecutive fetches that depend on each other in Redux Toolkit

I am new to the new way of doing things in Redux and I am a little confused.

I want to call one API endpoint to get an account Id and a category Id. Once I grab those, I want to make another request to another API endpoint to get a list of transactions.

My createApi function is like this:

export const accountApiSlice = createApi({
  reducerPath: "api",
  baseQuery: fetchBaseQuery({
    prepareHeaders(headers) {
      headers.set("authorization", token);

      return headers;
    },
  }),
  endpoints(builder) {
    return {
      fetchAccount: builder.query<AccountEndpointResponse, void>({
        query() {
          return `/accounts`;
        },
      }),
      fetchTransactions: builder.query<
        TransactionsEndpointResponse,
        { accountId: string; categoryId: string; changesSince: string }
      >({
        query({accountId, categoryId, changesSince}) {
          return `feed/account/${accountId}/category/${categoryId}?changesSince=${changesSince}`;
        },
      }),
    };
  },
});

The changesSince param is just an ISO DateTime that I generate myself.

In my App.tsx I have:

function App() {
    const { data, isSuccess } = useFetchAccountQuery();

    let accountId = data?.accounts[0].accountUid;
    let categoryId = data?.accounts[0].defaultCategory;

    return ( 
        <header className="App-header">
            <p>Number of accounts fetched: {data?.accounts.length}</p>
            <p>Account Id: {accountId}</p>
            <p>Category Id: {categoryId}</p>

            { accountId && categoryId && <TransactionsTable accountId={accountId} categoryId={categoryId} /> }
        </header>
    );
}

export default App;

Finally, in my TransactionsTable component, I have:

import { skipToken } from "@reduxjs/toolkit/dist/query";
import moment from "moment";
import { useFetchTransactionsQuery } from "./accountApiSlice";

interface TransactionsProps {
  accountId: string;
  categoryId: string;
}

const TransactionsTable = (props: TransactionsProps) => {
  const changesSince: string = moment().subtract(7, "d").toISOString();

  const { data, error, isSuccess } = useFetchTransactionsQuery({
    accountId: props.accountId,
    categoryId: props.categoryId,
    changesSince,
  }, skipToken);

  return (
    <>
      {isSuccess && (
        <div>
          <h1>Number of transactions: {data?.feedItems.length}</h1>
        </div>
      )}

      {error && <p>{error.toString()}</p>}
    </>
  );
};

export default TransactionsTable;

I am not 100% sure of my approach. I feel like I'm doing something wrong. I feel like I shouldn't be passing the account Id and category Id as props to the TransactionsTable component. I feel like I should instead access those from the state directly, but I wasn't sure how.

Secondly, my fetching of the transactions should trigger and render on the page, but it isn't and again I'm not sure why.

I tried to use the skipToken technique, like so:

  const { data, error, isSuccess } = useFetchTransactionsQuery({
    accountId: props.accountId,
    categoryId: props.categoryId,
    changesSince,
  }, skipToken);

But TypeScript was not happy, I got the error:

Type 'unique symbol' has no properties in common with type 'UseQuerySubscriptionOptions & UseQueryStateOptions<QueryDefinition<{ accountId: string | undefined; categoryId: string | undefined; changesSince: string | undefined; }, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, never, TransactionsEndpointResponse, "api">, UseQueryStateDef...'.ts(2559)

However, nothing seems to have changed. I don't get Number of transactions: <some number> . What am I missing?

skipToken should be passed in instead of the first parameter, like:

useFetchTransactionsQuery(
  someCondition ? realArgument : skipToken
)

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