useXxxReducer
This commit is contained in:
parent
9ec2059c4a
commit
b58c71c876
@ -1,31 +1,34 @@
|
||||
import './App.css';
|
||||
import React, { useReducer } from 'react'
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom"
|
||||
import React from 'react';
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
|
||||
import Header from "./container/Header"
|
||||
import Leaderboard from "./container/Leaderboard"
|
||||
import Game from "./components/Game"
|
||||
import About from "./components/About"
|
||||
|
||||
import Polling from './flux/polling';
|
||||
import User from './flux/user';
|
||||
import usePollingReducer from './reducer/polling';
|
||||
import useUserReducer from './reducer/user';
|
||||
import useLeaderboardReducer from './reducer/leaderboard';
|
||||
|
||||
import useLeaderboardApi from './api/leaderboard';
|
||||
import useUserApi from './api/user';
|
||||
|
||||
function App() {
|
||||
const pollingFlux = useReducer(Polling.reducer, Polling.initialState);
|
||||
const userFlux = useReducer(User.reducer, User.initialState);
|
||||
const pollingReducer = usePollingReducer();
|
||||
const userReducer = useUserReducer();
|
||||
const leaderboardReducer = useLeaderboardReducer();
|
||||
|
||||
const leaderboardApi = useLeaderboardApi(pollingFlux);
|
||||
const userApi = useUserApi(userFlux);
|
||||
const leaderboardApi = useLeaderboardApi(leaderboardReducer);
|
||||
const userApi = useUserApi(userReducer);
|
||||
|
||||
const leaderboard = leaderboardApi.get();
|
||||
const leaderboard = leaderboardApi.get(pollingReducer);
|
||||
const user = userApi.get();
|
||||
|
||||
return (
|
||||
<div className="App" >
|
||||
<BrowserRouter>
|
||||
<Header pollingFlux={pollingFlux} />
|
||||
<Header pollingReducer={pollingReducer} />
|
||||
<Routes>
|
||||
{/* https://stackoverflow.com/questions/40541994/multiple-path-names-for-a-same-component-in-react-router */}
|
||||
<Route path="/game" element={<Game />} />
|
||||
|
@ -2,19 +2,26 @@ import usePolling from "../util/Polling"
|
||||
|
||||
const uri = '/api/leaderboard';
|
||||
|
||||
export default function useLeaderboardApi([polling, dispatchPolling]) {
|
||||
export default function useLeaderboardApi(leaderboardReducer) {
|
||||
const [leaderboard, dispatchLeaderboaed] = leaderboardReducer;
|
||||
|
||||
const useGet = (pollingReducer) => {
|
||||
const [polling, dispatchPolling] = pollingReducer;
|
||||
|
||||
const useGet = () => {
|
||||
const mode = (polling.enabled === true)
|
||||
? { interval_sec: 300 } // update leaderbord stats every 5 min
|
||||
: { interval_stop: true } // user has fliped OfflineToggel
|
||||
|
||||
const [leaderboard, isFetching] = usePolling(uri, mode);
|
||||
const [table, isFetching] = usePolling(uri, mode);
|
||||
|
||||
if (polling.leaderboard !== isFetching) {
|
||||
dispatchPolling({ type: 'next', leaderboard: isFetching });
|
||||
}
|
||||
|
||||
if (leaderboard.table !== table) {
|
||||
dispatchLeaderboaed({ type: 'next', table });
|
||||
}
|
||||
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@ import { NavLink } from "react-router-dom";
|
||||
import OnlineToggle from '../components/OnlineToggle';
|
||||
import Wobler from '../components/Wobler';
|
||||
|
||||
export default function Header({ pollingFlux }) {
|
||||
const [polling, dispatchPolling] = pollingFlux;
|
||||
export default function Header({ pollingReducer }) {
|
||||
const [polling, dispatchPolling] = pollingReducer;
|
||||
|
||||
return (
|
||||
<div className='Header'>
|
||||
@ -33,4 +33,4 @@ export default function Header({ pollingFlux }) {
|
||||
</nav>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -4,14 +4,15 @@ import Loading from '../components/Loading';
|
||||
|
||||
export default function Leaderboard({ leaderboard, user }) {
|
||||
|
||||
if (leaderboard == null)
|
||||
const table = leaderboard?.table;
|
||||
if (!table)
|
||||
return <Loading />
|
||||
|
||||
const isCurrentUser = (playerName) =>
|
||||
user.isCurrentUser(playerName) === true ? true : null;
|
||||
user?.isCurrentUser(playerName) === true ? true : null;
|
||||
|
||||
const tableRows = Object.keys(leaderboard).map(playerName => {
|
||||
var rank = leaderboard[playerName];
|
||||
const tableRows = Object.keys(table).map(playerName => {
|
||||
var rank = table[playerName];
|
||||
|
||||
return <tr key={playerName} className={isCurrentUser(playerName) && 'currentuser'}>
|
||||
<td>{playerName}</td>
|
||||
|
@ -1,28 +0,0 @@
|
||||
import { localeCompare } from '../util/Locale'
|
||||
import StateHelper from '../util/StateHelper';
|
||||
|
||||
export const userInitialState = {
|
||||
username: '',
|
||||
isCurrentUser: function (otherUsername) {
|
||||
return localeCompare(this.username, otherUsername)
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export function userReducer(state, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case 'next':
|
||||
return StateHelper.next(state, action);
|
||||
|
||||
default:
|
||||
throw Error('Unknown action.type: ' + action.type);
|
||||
}
|
||||
}
|
||||
|
||||
const User = {
|
||||
reducer: userReducer,
|
||||
initialState: userInitialState
|
||||
};
|
||||
|
||||
export default User;
|
21
webapp/src/reducer/leaderboard.js
Normal file
21
webapp/src/reducer/leaderboard.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { useReducer } from 'react';
|
||||
import { nextState } from '../util/StateHelper';
|
||||
|
||||
export const leaderboardInitialState = {
|
||||
table: null,
|
||||
};
|
||||
|
||||
export function leaderboardReducer(state, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case 'next':
|
||||
return nextState(state, action);
|
||||
|
||||
default:
|
||||
throw Error('LeaderboardReducer: Unknown action.type', action.type);
|
||||
}
|
||||
}
|
||||
|
||||
export default function useLeaderboardReducer() {
|
||||
return useReducer(leaderboardReducer, leaderboardInitialState);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { useLocalStorage } from '../util/PersistentStorage'
|
||||
import { useReducer } from 'react';
|
||||
import { useLocalStorage } from '../util/PersistentStorage';
|
||||
import { nextState } from '../util/StateHelper';
|
||||
|
||||
const Persistent = (() => {
|
||||
@ -33,9 +34,6 @@ export function pollingReducer(curntState, action) {
|
||||
}
|
||||
}
|
||||
|
||||
const Polling = {
|
||||
reducer: pollingReducer,
|
||||
initialState: pollingInitialState
|
||||
};
|
||||
|
||||
export default Polling
|
||||
export default function usePollingReducer() {
|
||||
return useReducer(pollingReducer, pollingInitialState);
|
||||
}
|
26
webapp/src/reducer/user.js
Normal file
26
webapp/src/reducer/user.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { useReducer } from 'react';
|
||||
import { localeCompare } from '../util/Locale';
|
||||
import { nextState } from '../util/StateHelper';
|
||||
|
||||
export const userInitialState = {
|
||||
username: '',
|
||||
|
||||
isCurrentUser: function (otherUsername) {
|
||||
return localeCompare(this.username, otherUsername)
|
||||
}
|
||||
};
|
||||
|
||||
export function userReducer(state, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case 'next':
|
||||
return nextState(state, action);
|
||||
|
||||
default:
|
||||
throw Error('Unknown action.type', action.type);
|
||||
}
|
||||
}
|
||||
|
||||
export default function useUserReducer() {
|
||||
return useReducer(userReducer, userInitialState);
|
||||
}
|
@ -47,7 +47,7 @@ export default function usePolling(url, mode) {
|
||||
}, [url, mode, isFetching, cache, fetchData, delayID]);
|
||||
|
||||
return [
|
||||
cache, // API response
|
||||
cache, // API responce
|
||||
isFetching // true / false
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user