From 3ffb5c045da50a49aad2dbe48a381fc47bf50ca1 Mon Sep 17 00:00:00 2001 From: Tobias Prima Date: Wed, 20 Mar 2024 01:06:53 +0800 Subject: [PATCH] feat: apislice --- package-lock.json | 91 ++++++++++++++++++++++++--- package.json | 1 - src/{features => app}/api/apiSlice.js | 0 src/app/store.js | 13 ++++ src/features/todos/TodoList.js | 16 +++++ src/index.js | 10 +-- src/setupTests.js | 4 -- 7 files changed, 117 insertions(+), 18 deletions(-) rename src/{features => app}/api/apiSlice.js (100%) create mode 100644 src/app/store.js diff --git a/package-lock.json b/package-lock.json index 48738c4..6b851c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^8.1.3", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, @@ -4588,6 +4589,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -4709,8 +4719,7 @@ "node_modules/@types/prop-types": { "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "dev": true + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/q": { "version": "1.5.8", @@ -4731,7 +4740,6 @@ "version": "18.2.66", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.66.tgz", "integrity": "sha512-OYTmMI4UigXeFMF/j4uv0lBBEbongSgptPrHBxqME44h9+yNov+oL6Z3ocJKo0WyXR84sQUNeyIp9MRfckvZpg==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4742,7 +4750,7 @@ "version": "18.2.22", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.22.tgz", "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -4763,8 +4771,7 @@ "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/semver": { "version": "7.5.8", @@ -4824,6 +4831,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -7148,8 +7160,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -9753,6 +9764,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -16303,6 +16327,49 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -18741,6 +18808,14 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index cc3c996..1bfb026 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ }, "devDependencies": { "@babel/core": "^7.24.1", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-env": "^7.24.1", "@babel/preset-react": "^7.24.1", "@testing-library/react": "^14.2.1", diff --git a/src/features/api/apiSlice.js b/src/app/api/apiSlice.js similarity index 100% rename from src/features/api/apiSlice.js rename to src/app/api/apiSlice.js diff --git a/src/app/store.js b/src/app/store.js new file mode 100644 index 0000000..d58dc5b --- /dev/null +++ b/src/app/store.js @@ -0,0 +1,13 @@ +import { configureStore } from "@reduxjs/toolkit"; +import { apiSlice } from "./api/apiSlice"; +import { setupListeners } from "@reduxjs/toolkit/query"; + +export const store = configureStore({ + reducer: { + [apiSlice.reducerPath]: apiSlice.reducer, + }, + middleware: getDefaultMiddleware => getDefaultMiddleware().concat(apiSlice.middleware), + devTools: false +}) + +setupListeners(store.dispatch); \ No newline at end of file diff --git a/src/features/todos/TodoList.js b/src/features/todos/TodoList.js index c9a5974..3c61bb5 100644 --- a/src/features/todos/TodoList.js +++ b/src/features/todos/TodoList.js @@ -2,10 +2,19 @@ import React from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faTrash, faUpload } from '@fortawesome/free-solid-svg-icons' import { useState } from 'react' +import { useGetTodosQuery } from '../../app/api/apiSlice' const TodoList = () => { const [ newTodo, setNewTodo ] = useState('') + const { + data: todos, + isLoading, + isSuccess, + isError, + error + } = useGetTodosQuery() + const handleSubmit = (e)=> { e.preventDefault() //addTodo @@ -30,6 +39,13 @@ const TodoList = () => { let content; + if (isLoading) { + content =

Loading ...

+ } else if (isSuccess){ + content = JSON.stringify(todos) + } else if (isError) { + content =

{error.message || 'Error fetching todos'}

+ } return (
diff --git a/src/index.js b/src/index.js index 6d6bb8b..e13abdb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,16 +1,16 @@ import React from 'react'; -import ReactDOM from 'react-dom/client'; +import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; -import { ApiProvider } from '@reduxjs/toolkit/dist/query/react'; -import { apiSlice } from './features/api/apiSlice'; +import { Provider } from 'react-redux'; +import { store } from './app/store'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + - + ); diff --git a/src/setupTests.js b/src/setupTests.js index 8f2609b..7b0828b 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -1,5 +1 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom';