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 ponent, 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 ponent. Thanks, everyone!
The Code:
// LoginPage.jsx
import React, { Component } from 'react'
import PT from 'prop-types'
import LoginForm from './ponents/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' }
}),
}),
}),
})
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 ponent, 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 ponent. Thanks, everyone!
The Code:
// LoginPage.jsx
import React, { Component } from 'react'
import PT from 'prop-types'
import LoginForm from './ponents/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' }
}),
}),
}),
})
Share
Improve this question
edited Jul 29, 2021 at 18:46
sgarcia.dev
asked Jul 29, 2021 at 18:40
sgarcia.devsgarcia.dev
6,20014 gold badges51 silver badges84 bronze badges
2 Answers
Reset to default 5The "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.
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/rtk-query/usage/usage-without-react-hooks