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