Reputation: 6170
Ok, I think I've gone through almost all of RTK Query's docs, and read up on RTK Query's caching. Seems like it's a pretty big part of it, even if its not something I need at the moment.
So, I'm trying to do a simple query using RKT Query in a class-based component, and then select from the Redux Store the isLoading state for the endpoint call. However, currently in the render() {}
of my LoginPage.jsx
, the endpoint.<name>.select()(state)
call on mapStateToProps
within LoginPageContainer.jsx
doesn't seem to be working. (See code below).
From looking at the examples from the docs on using RTK Query on classes, it looks like I'm missing a "cache key" in the .select(<cache_key>)(state)
call. However, I haven't incorporated tags in my endpoint yet (I believe I don't have a need for them yet).
My question:
Can someone shed some light on what's the proper use on RTK Query generated endpoint's select()
method used outside of React Hooks? I understand the idea behind cache tags for automatic re-fetching (but that's not likely what's wrong here), but I'm not sure how or what cache key I'm missing here to just get the running endpoint query state in a class component. Thanks, everyone!
The Code:
// LoginPage.jsx
import React, { Component } from 'react'
import PT from 'prop-types'
import LoginForm from './components/LoginForm'
export default class LoginPage extends Component {
static propTypes = {
loginWithUsername: PT.func.isRequired,
loginWithUsernameState: PT.object.isRequired
}
render() {
// This value never updates
const { isLoading } = this.props.loginWithUsernameState
// always outputs "{"status":"uninitialized","isUninitialized":true,"isLoading":false,"isSuccess":false,"isError":false}"
// Even during and after running the `loginWithUsername` endpoint query
console.log(this.props.loginWithUsernameState)
return (
<div>
{isLoading && 'Loading ...'}
<LoginForm
onSubmit={(values) => this.props.loginWithUsername(values)} />
</div>
)
}
}
// LoginPageContainer.jsx
import { connect } from 'react-redux'
import { teacherApi } from './api'
import LoginPage from './LoginPage'
const { loginWithUsername } = teacherApi.endpoints
const mapStateToProps = (state) => ({
loginWithUsernameState: loginWithUsername.select()(state)
})
const mapDispatchToProps = (dispatch) => ({
loginWithUsername: (payload) => dispatch(loginWithUsername.initiate(payload))
})
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)
// api.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
export const teacherApi = createApi({
reducerPath: 'teacherApi',
baseQuery: fetchBaseQuery({ baseUrl: '/teacher/' }),
endpoints: (builder) => ({
loginWithUsername: builder.query({
query: (data) => ({
url: 'login',
method: 'post',
body: data,
headers: { 'Content-Type': 'application/json' }
}),
}),
}),
})
Upvotes: 1
Views: 8348
Reputation: 25
const result = api.endpoints.getPosts.select()(state)
const { data, status, error } = result
Note that unlike the auto-generated query hooks, derived booleans such as isLoading, isFetching, isSuccess are not available here. The raw status enum is provided instead.
https://redux-toolkit.js.org/rtk-query/usage/usage-without-react-hooks
Upvotes: 1
Reputation: 67547
The "cache key" passed to endpoint.select()
is the same variable you're passing to your hook:
useGetSomeItemQuery("a");
useGetSomeItemQuery("b");
const selectSomeItemA = endpoint.select("a");
const selectSomeItemB = endpoint.select("b");
const itemAREsults = selectSomeItemA(state);
const itemBResults = selectSomeItemB(state);
This results in looking up state => state[apiSlice.reducerPath].queries["getSomeItem('a')"]
, or whatever the exact cached data field is for that item.
Upvotes: 5