From 2aa097e039f689fecfd51a2530ae4de77a1bb7d6 Mon Sep 17 00:00:00 2001 From: Jimmy Li Date: Fri, 25 Feb 2022 01:25:53 -0500 Subject: [PATCH] Implement routing After some agonizing, I discovered that the latest version of react-router-dom (v6) is supported by redux-first-history Connected-react-router seems to have not been maintained to support react-router v6: https://github.com/supasate/connected-react-router/issues/543 --- package.json | 5 ++++ setupTests.ts | 1 + src/client/components/App/App.spec.tsx | 23 +++++++++++++++++ src/client/components/App/App.tsx | 23 ++++++++++++++--- src/client/redux/store.ts | 23 ++++++++++++++--- yarn.lock | 34 +++++++++++++++++++++++++- 6 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 src/client/components/App/App.spec.tsx diff --git a/package.json b/package.json index ba79604..d76e4c6 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,16 @@ "@reduxjs/toolkit": "^1.7.2", "@types/lodash.clonedeep": "^4.5.6", "express": "^4.17.2", + "history": "^5.3.0", "lodash.clonedeep": "^4.5.0", "lodash.shuffle": "^4.2.0", "react": "^17.0.2", "react-dom": "^17.0.2", "react-is": "^17.0.2", "react-redux": "^7.2.6", + "react-router-dom": "^6.2.1", + "redux": "^4.1.2", + "redux-first-history": "^5.0.8", "socket.io": "^4.4.1", "socket.io-client": "^4.4.1", "styled-components": "^5.3.3" @@ -38,6 +42,7 @@ "@types/styled-components": "^5.1.23", "@typescript-eslint/eslint-plugin": "^5.9.1", "@typescript-eslint/parser": "^5.9.1", + "core-js": "^3.21.1", "eslint": "^8.7.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^16.1.0", diff --git a/setupTests.ts b/setupTests.ts index 666127a..3655dae 100644 --- a/setupTests.ts +++ b/setupTests.ts @@ -1 +1,2 @@ import '@testing-library/jest-dom/extend-expect'; +import 'core-js'; diff --git a/src/client/components/App/App.spec.tsx b/src/client/components/App/App.spec.tsx new file mode 100644 index 0000000..0373ec8 --- /dev/null +++ b/src/client/components/App/App.spec.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { Provider } from 'react-redux'; +import { fireEvent, screen, render } from '@testing-library/react'; + +import { App } from './App'; +import { store } from '@/client/redux/store'; + +describe('App', () => { + it('goes to the compact decklist view', () => { + render( + + + + ); + expect( + screen.queryByText('Deal 3 damage to any target') + ).toBeInTheDocument(); + fireEvent.click(screen.getByText('Compact Deck List')); + expect( + screen.queryByText('Deal 3 damage to any target') + ).not.toBeInTheDocument(); + }); +}); diff --git a/src/client/components/App/App.tsx b/src/client/components/App/App.tsx index fadfc07..b698e3e 100644 --- a/src/client/components/App/App.tsx +++ b/src/client/components/App/App.tsx @@ -1,14 +1,17 @@ import React, { useEffect } from 'react'; import { io, Socket } from 'socket.io-client'; import { useDispatch } from 'react-redux'; +import { HistoryRouter as Router } from 'redux-first-history/rr6'; +import { Link, Route, Routes } from 'react-router-dom'; import { DeckList } from '../DeckList'; import { CompactDeckList } from '../CompactDeckList'; import { makeSampleDeck1 } from '@/factories/deck'; import { disconnectUser, initializeUser } from '@/client/redux/user'; +import { AppDispatch, history } from '@/client/redux/store'; export const App: React.FC = () => { - const dispatch = useDispatch(); + const dispatch: AppDispatch = useDispatch(); const socket: Socket = io(); useEffect(() => { socket.on('connect', () => { @@ -23,8 +26,22 @@ export const App: React.FC = () => { return (
- - + + + Deck List 1 +
+ Compact Deck List + + + } /> + } + /> + } /> + +
+
); }; diff --git a/src/client/redux/store.ts b/src/client/redux/store.ts index 29b665d..b382365 100644 --- a/src/client/redux/store.ts +++ b/src/client/redux/store.ts @@ -1,15 +1,30 @@ -import { configureStore } from '@reduxjs/toolkit'; +import { configureStore, combineReducers } from '@reduxjs/toolkit'; +import { createReduxHistoryContext } from 'redux-first-history'; +import { createBrowserHistory } from 'history'; +import { applyMiddleware } from 'redux'; + import { userReducer, userSlice } from './user'; -export const store = configureStore({ - reducer: { +const { createReduxHistory, routerMiddleware, routerReducer } = + createReduxHistoryContext({ + history: createBrowserHistory(), + }); + +const createRootReducer = () => + combineReducers({ + router: routerReducer, user: userReducer, - }, + }); + +export const store = configureStore({ + reducer: createRootReducer(), devTools: true, + enhancers: [applyMiddleware(routerMiddleware)], preloadedState: { user: userSlice.getInitialState(), }, }); +export const history = createReduxHistory(store); // Infer the `RootState` and `AppDispatch` types from the store itself export type RootState = ReturnType; diff --git a/yarn.lock b/yarn.lock index 6ad0338..ebe070a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -262,7 +262,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.9.2": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== @@ -1803,6 +1803,11 @@ cookie@0.4.2, cookie@~0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +core-js@^3.21.1: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" + integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== + cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -2785,6 +2790,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +history@^5.2.0, history@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" + integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== + dependencies: + "@babel/runtime" "^7.7.6" + hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -4391,6 +4403,21 @@ react-redux@^7.2.6: prop-types "^15.7.2" react-is "^17.0.2" +react-router-dom@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec" + integrity sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA== + dependencies: + history "^5.2.0" + react-router "6.2.1" + +react-router@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.2.1.tgz#be2a97a6006ce1d9123c28934e604faef51448a3" + integrity sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg== + dependencies: + history "^5.2.0" + react@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" @@ -4421,6 +4448,11 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redux-first-history@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/redux-first-history/-/redux-first-history-5.0.8.tgz#672ccee4837f2453d071f8e4c9e47137bc293152" + integrity sha512-JwTKQwEiIxhRk0g234+GlSQtiAUBcBOeHZJvY2YEFMO80ANTHme16Ip2a998hkhzGtKJxUKragOCUiGaTiwOHw== + redux-thunk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714"