mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-27 00:19:55 +03:00
chore: copy rtk-query example from toolkit
This commit is contained in:
parent
326cfdf217
commit
1449d5a9c2
1
packages/redux-devtools/examples/rtk-query-polling/.env
Normal file
1
packages/redux-devtools/examples/rtk-query-polling/.env
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SKIP_PREFLIGHT_CHECK=true
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "rtk-query-example-polling",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "",
|
||||||
|
"keywords": [],
|
||||||
|
"main": "src/index.tsx",
|
||||||
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^1.6.0",
|
||||||
|
"react": "^16.3.0",
|
||||||
|
"react-dom": "^16.3.0",
|
||||||
|
"react-redux": "7.2.2",
|
||||||
|
"react-scripts": "4.0.2",
|
||||||
|
"remote-redux-devtools": "0.5.16"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "17.0.0",
|
||||||
|
"@types/react-dom": "17.0.0",
|
||||||
|
"@types/react-redux": "7.1.9",
|
||||||
|
"typescript": "4.1.3"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": [
|
||||||
|
"react-app"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not ie <= 11",
|
||||||
|
"not op_mini all"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="theme-color" content="#000000">
|
||||||
|
<!--
|
||||||
|
manifest.json provides metadata used when your web app is added to the
|
||||||
|
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||||
|
-->
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||||
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||||
|
<!--
|
||||||
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
|
|
||||||
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||||
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
|
-->
|
||||||
|
<title>React App</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
You need to enable JavaScript to run this app.
|
||||||
|
</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
|
This HTML file is a template.
|
||||||
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file.
|
||||||
|
The build step will place the bundled scripts into the <body> tag.
|
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
|
-->
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"short_name": "RTK Query Polling Example",
|
||||||
|
"name": "Polling Example",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { Pokemon } from './Pokemon'
|
||||||
|
import { PokemonName, POKEMON_NAMES } from './pokemon.data'
|
||||||
|
import './styles.css'
|
||||||
|
|
||||||
|
const getRandomPokemonName = () =>
|
||||||
|
POKEMON_NAMES[Math.floor(Math.random() * POKEMON_NAMES.length)]
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
const [pokemon, setPokemon] = useState<PokemonName[]>(['bulbasaur'])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setPokemon((prev) => [...prev, getRandomPokemonName()])
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Add random pokemon
|
||||||
|
</button>
|
||||||
|
<button onClick={() => setPokemon((prev) => [...prev, 'bulbasaur'])}>
|
||||||
|
Add bulbasaur
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{pokemon.map((name, index) => (
|
||||||
|
<Pokemon key={index} name={name} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { useState, version } from 'react'
|
||||||
|
import { useGetPokemonByNameQuery } from './services/pokemon'
|
||||||
|
import type { PokemonName } from './pokemon.data'
|
||||||
|
|
||||||
|
console.log(version);
|
||||||
|
|
||||||
|
const intervalOptions = [
|
||||||
|
{ label: 'Off', value: 0 },
|
||||||
|
{ label: '3s', value: 3000 },
|
||||||
|
{ label: '5s', value: 5000 },
|
||||||
|
{ label: '10s', value: 10000 },
|
||||||
|
{ label: '1m', value: 60000 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const getRandomIntervalValue = () =>
|
||||||
|
intervalOptions[Math.floor(Math.random() * intervalOptions.length)].value
|
||||||
|
|
||||||
|
export function Pokemon({ name }: { name: PokemonName }) {
|
||||||
|
const [pollingInterval, setPollingInterval] = useState(
|
||||||
|
getRandomIntervalValue()
|
||||||
|
)
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
isLoading,
|
||||||
|
isFetching,
|
||||||
|
refetch,
|
||||||
|
} = useGetPokemonByNameQuery(name, {
|
||||||
|
pollingInterval,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
float: 'left',
|
||||||
|
textAlign: 'center',
|
||||||
|
...(isFetching ? { background: '#e6ffe8' } : {}),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{error ? (
|
||||||
|
<>Oh no, there was an error loading {name}</>
|
||||||
|
) : isLoading ? (
|
||||||
|
<>Loading...</>
|
||||||
|
) : data ? (
|
||||||
|
<>
|
||||||
|
<h3>{data.species.name}</h3>
|
||||||
|
<div style={{ minWidth: 96, minHeight: 96 }}>
|
||||||
|
<img
|
||||||
|
src={data.sprites.front_shiny}
|
||||||
|
alt={data.species.name}
|
||||||
|
style={{ ...(isFetching ? { opacity: 0.3 } : {}) }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label style={{ display: 'block' }}>Polling interval</label>
|
||||||
|
<select
|
||||||
|
value={pollingInterval}
|
||||||
|
onChange={({ target: { value } }) =>
|
||||||
|
setPollingInterval(Number(value))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{intervalOptions.map(({ label, value }) => (
|
||||||
|
<option key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onClick={refetch} disabled={isFetching}>
|
||||||
|
{isFetching ? 'Loading' : 'Manually refetch'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
'No Data'
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { render } from 'react-dom'
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import App from './App'
|
||||||
|
import { store } from './store'
|
||||||
|
|
||||||
|
const rootElement = document.getElementById('root')
|
||||||
|
|
||||||
|
render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<App />
|
||||||
|
</Provider> ,
|
||||||
|
rootElement
|
||||||
|
);
|
|
@ -0,0 +1,155 @@
|
||||||
|
export const POKEMON_NAMES = [
|
||||||
|
'bulbasaur',
|
||||||
|
'ivysaur',
|
||||||
|
'venusaur',
|
||||||
|
'charmander',
|
||||||
|
'charmeleon',
|
||||||
|
'charizard',
|
||||||
|
'squirtle',
|
||||||
|
'wartortle',
|
||||||
|
'blastoise',
|
||||||
|
'caterpie',
|
||||||
|
'metapod',
|
||||||
|
'butterfree',
|
||||||
|
'weedle',
|
||||||
|
'kakuna',
|
||||||
|
'beedrill',
|
||||||
|
'pidgey',
|
||||||
|
'pidgeotto',
|
||||||
|
'pidgeot',
|
||||||
|
'rattata',
|
||||||
|
'raticate',
|
||||||
|
'spearow',
|
||||||
|
'fearow',
|
||||||
|
'ekans',
|
||||||
|
'arbok',
|
||||||
|
'pikachu',
|
||||||
|
'raichu',
|
||||||
|
'sandshrew',
|
||||||
|
'sandslash',
|
||||||
|
'nidoran',
|
||||||
|
'nidorina',
|
||||||
|
'nidoqueen',
|
||||||
|
'nidoran',
|
||||||
|
'nidorino',
|
||||||
|
'nidoking',
|
||||||
|
'clefairy',
|
||||||
|
'clefable',
|
||||||
|
'vulpix',
|
||||||
|
'ninetales',
|
||||||
|
'jigglypuff',
|
||||||
|
'wigglytuff',
|
||||||
|
'zubat',
|
||||||
|
'golbat',
|
||||||
|
'oddish',
|
||||||
|
'gloom',
|
||||||
|
'vileplume',
|
||||||
|
'paras',
|
||||||
|
'parasect',
|
||||||
|
'venonat',
|
||||||
|
'venomoth',
|
||||||
|
'diglett',
|
||||||
|
'dugtrio',
|
||||||
|
'meowth',
|
||||||
|
'persian',
|
||||||
|
'psyduck',
|
||||||
|
'golduck',
|
||||||
|
'mankey',
|
||||||
|
'primeape',
|
||||||
|
'growlithe',
|
||||||
|
'arcanine',
|
||||||
|
'poliwag',
|
||||||
|
'poliwhirl',
|
||||||
|
'poliwrath',
|
||||||
|
'abra',
|
||||||
|
'kadabra',
|
||||||
|
'alakazam',
|
||||||
|
'machop',
|
||||||
|
'machoke',
|
||||||
|
'machamp',
|
||||||
|
'bellsprout',
|
||||||
|
'weepinbell',
|
||||||
|
'victreebel',
|
||||||
|
'tentacool',
|
||||||
|
'tentacruel',
|
||||||
|
'geodude',
|
||||||
|
'graveler',
|
||||||
|
'golem',
|
||||||
|
'ponyta',
|
||||||
|
'rapidash',
|
||||||
|
'slowpoke',
|
||||||
|
'slowbro',
|
||||||
|
'magnemite',
|
||||||
|
'magneton',
|
||||||
|
"farfetch'd",
|
||||||
|
'doduo',
|
||||||
|
'dodrio',
|
||||||
|
'seel',
|
||||||
|
'dewgong',
|
||||||
|
'grimer',
|
||||||
|
'muk',
|
||||||
|
'shellder',
|
||||||
|
'cloyster',
|
||||||
|
'gastly',
|
||||||
|
'haunter',
|
||||||
|
'gengar',
|
||||||
|
'onix',
|
||||||
|
'drowzee',
|
||||||
|
'hypno',
|
||||||
|
'krabby',
|
||||||
|
'kingler',
|
||||||
|
'voltorb',
|
||||||
|
'electrode',
|
||||||
|
'exeggcute',
|
||||||
|
'exeggutor',
|
||||||
|
'cubone',
|
||||||
|
'marowak',
|
||||||
|
'hitmonlee',
|
||||||
|
'hitmonchan',
|
||||||
|
'lickitung',
|
||||||
|
'koffing',
|
||||||
|
'weezing',
|
||||||
|
'rhyhorn',
|
||||||
|
'rhydon',
|
||||||
|
'chansey',
|
||||||
|
'tangela',
|
||||||
|
'kangaskhan',
|
||||||
|
'horsea',
|
||||||
|
'seadra',
|
||||||
|
'goldeen',
|
||||||
|
'seaking',
|
||||||
|
'staryu',
|
||||||
|
'starmie',
|
||||||
|
'mr. mime',
|
||||||
|
'scyther',
|
||||||
|
'jynx',
|
||||||
|
'electabuzz',
|
||||||
|
'magmar',
|
||||||
|
'pinsir',
|
||||||
|
'tauros',
|
||||||
|
'magikarp',
|
||||||
|
'gyarados',
|
||||||
|
'lapras',
|
||||||
|
'ditto',
|
||||||
|
'eevee',
|
||||||
|
'vaporeon',
|
||||||
|
'jolteon',
|
||||||
|
'flareon',
|
||||||
|
'porygon',
|
||||||
|
'omanyte',
|
||||||
|
'omastar',
|
||||||
|
'kabuto',
|
||||||
|
'kabutops',
|
||||||
|
'aerodactyl',
|
||||||
|
'snorlax',
|
||||||
|
'articuno',
|
||||||
|
'zapdos',
|
||||||
|
'moltres',
|
||||||
|
'dratini',
|
||||||
|
'dragonair',
|
||||||
|
'dragonite',
|
||||||
|
'mewtwo',
|
||||||
|
'mew',
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export type PokemonName = typeof POKEMON_NAMES[number]
|
5
packages/redux-devtools/examples/rtk-query-polling/src/react-app-env.d.ts
vendored
Normal file
5
packages/redux-devtools/examples/rtk-query-polling/src/react-app-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/// <reference types="react-scripts" />
|
||||||
|
|
||||||
|
declare module '@redux-devtools/app';
|
||||||
|
|
||||||
|
declare module 'remote-redux-devtools';
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||||
|
import type { PokemonName } from '../pokemon.data'
|
||||||
|
|
||||||
|
export const pokemonApi = createApi({
|
||||||
|
reducerPath: 'pokemonApi',
|
||||||
|
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
getPokemonByName: builder.query({
|
||||||
|
query: (name: PokemonName) => `pokemon/${name}`,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Export hooks for usage in functional components
|
||||||
|
export const { useGetPokemonByNameQuery } = pokemonApi
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { configureStore } from '@reduxjs/toolkit'
|
||||||
|
import { pokemonApi } from './services/pokemon'
|
||||||
|
import devToolsEnhancer from 'remote-redux-devtools';
|
||||||
|
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
[pokemonApi.reducerPath]: pokemonApi.reducer,
|
||||||
|
},
|
||||||
|
devTools: false,
|
||||||
|
// adding the api middleware enables caching, invalidation, polling and other features of `rtk-query`
|
||||||
|
middleware: (getDefaultMiddleware) =>
|
||||||
|
getDefaultMiddleware().concat(pokemonApi.middleware),
|
||||||
|
enhancers : [devToolsEnhancer({ port: 8000, hostname: 'localhost' })]
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
.App {
|
||||||
|
font-family: sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"./src/**/*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"target": "es5",
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true
|
||||||
|
}
|
||||||
|
}
|
11507
packages/redux-devtools/examples/rtk-query-polling/yarn.lock
Normal file
11507
packages/redux-devtools/examples/rtk-query-polling/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user