From 2f8ae58f4f5cde892b4b6981a83a37edc1422a2c Mon Sep 17 00:00:00 2001 From: ditoaugusta Date: Tue, 24 Mar 2020 15:04:52 +0700 Subject: experiment: redux toolkit --- modern/jsconfig.json | 6 ++++++ modern/package.json | 1 + modern/src/DeviceList.js | 6 +++--- modern/src/MainMap.js | 9 +++++---- modern/src/SocketController.js | 8 ++++---- modern/src/index.js | 6 ++---- modern/src/store/index.js | 5 +++++ modern/src/store/modules/devices.js | 20 ++++++++++++++++++++ modern/src/store/modules/index.js | 12 ++++++++++++ modern/src/store/modules/positions.js | 16 ++++++++++++++++ 10 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 modern/jsconfig.json create mode 100644 modern/src/store/index.js create mode 100644 modern/src/store/modules/devices.js create mode 100644 modern/src/store/modules/index.js create mode 100644 modern/src/store/modules/positions.js (limited to 'modern') diff --git a/modern/jsconfig.json b/modern/jsconfig.json new file mode 100644 index 00000000..ec9aa3f7 --- /dev/null +++ b/modern/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "baseUrl": "src" + }, + "include": ["src"] +} \ No newline at end of file diff --git a/modern/package.json b/modern/package.json index 04c1b4aa..90b03d3f 100644 --- a/modern/package.json +++ b/modern/package.json @@ -5,6 +5,7 @@ "dependencies": { "@material-ui/core": "^4.9.7", "@material-ui/icons": "^4.9.1", + "@reduxjs/toolkit": "^1.2.5", "mapbox-gl": "^1.8.1", "ol": "^6.2.1", "ol-mapbox-style": "^6.0.1", diff --git a/modern/src/DeviceList.js b/modern/src/DeviceList.js index 03c5126c..88428007 100644 --- a/modern/src/DeviceList.js +++ b/modern/src/DeviceList.js @@ -10,15 +10,15 @@ import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import IconButton from '@material-ui/core/IconButton'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import Divider from '@material-ui/core/Divider'; -import { selectDevice } from './actions'; +import { devicesActions } from 'store/modules'; const mapStateToProps = state => ({ - devices: Array.from(state.devices.values()) + devices: Object.values(state.devices.items) }); class DeviceList extends Component { handleClick(device) { - this.props.dispatch(selectDevice(device)); + this.props.dispatch(devicesActions.select(device)); } render() { diff --git a/modern/src/MainMap.js b/modern/src/MainMap.js index 35b933b4..01230da9 100644 --- a/modern/src/MainMap.js +++ b/modern/src/MainMap.js @@ -4,8 +4,8 @@ import { connect } from 'react-redux'; import mapboxgl from 'mapbox-gl'; const calculateMapCenter = (state) => { - if (state.selectedDevice) { - const position = state.positions.get(state.selectedDevice); + if (state.devices.selectedId) { + const position = state.positions.items[state.devices.selectedId] || null; if (position) { return [position.longitude, position.latitude]; } @@ -14,8 +14,9 @@ const calculateMapCenter = (state) => { } const mapFeatureProperties = (state, position) => { + const device = state.devices.items[position.deviceId] || null; return { - name: state.devices.get(position.deviceId).name + name: device ? device.name : '' } } @@ -23,7 +24,7 @@ const mapStateToProps = state => ({ mapCenter: calculateMapCenter(state), data: { type: 'FeatureCollection', - features: Array.from(state.positions.values()).map(position => ({ + features: Object.values(state.positions.items).map(position => ({ type: 'Feature', geometry: { type: 'Point', diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js index b89845f2..10db17a4 100644 --- a/modern/src/SocketController.js +++ b/modern/src/SocketController.js @@ -1,6 +1,6 @@ import { Component } from 'react'; import { connect } from 'react-redux'; -import { updateDevices, updatePositions } from './actions'; +import { positionsActions, devicesActions } from 'store/modules'; const displayNotifications = events => { if ("Notification" in window) { @@ -31,10 +31,10 @@ class SocketController extends Component { socket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.devices) { - this.props.dispatch(updateDevices(data.devices)); + this.props.dispatch(devicesActions.update(data.devices)); } if (data.positions) { - this.props.dispatch(updatePositions(data.positions)); + this.props.dispatch(positionsActions.update(data.positions)); } if (data.events) { displayNotifications(data.events); @@ -46,7 +46,7 @@ class SocketController extends Component { fetch('/api/devices').then(response => { if (response.ok) { response.json().then(devices => { - this.props.dispatch(updateDevices(devices)); + this.props.dispatch(devicesActions.update(devices)); }); } this.connectSocket(); diff --git a/modern/src/index.js b/modern/src/index.js index 527a4d69..f501a083 100644 --- a/modern/src/index.js +++ b/modern/src/index.js @@ -3,12 +3,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom' import { Provider } from 'react-redux'; -import { createStore } from 'redux' -import rootReducer from './reducers'; + import App from './App'; import registerServiceWorker from './registerServiceWorker'; - -const store = createStore(rootReducer); +import store from './store'; ReactDOM.render(( diff --git a/modern/src/store/index.js b/modern/src/store/index.js new file mode 100644 index 00000000..c981c136 --- /dev/null +++ b/modern/src/store/index.js @@ -0,0 +1,5 @@ +import { configureStore } from '@reduxjs/toolkit'; + +import { rootReducer } from './modules'; + +export default configureStore({ reducer: rootReducer }); diff --git a/modern/src/store/modules/devices.js b/modern/src/store/modules/devices.js new file mode 100644 index 00000000..0d96e98d --- /dev/null +++ b/modern/src/store/modules/devices.js @@ -0,0 +1,20 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const { reducer, actions } = createSlice({ + name: 'devices', + initialState: { + items: {}, + selectedId: null + }, + reducers: { + update(state, action) { + action.payload.forEach(item => state.items[item['id']] = item); + }, + select(state, action) { + state.selectedId = action.payload.id; + } + } +}); + +export { actions as devicesActions }; +export { reducer as devicesReducer }; diff --git a/modern/src/store/modules/index.js b/modern/src/store/modules/index.js new file mode 100644 index 00000000..e2037c72 --- /dev/null +++ b/modern/src/store/modules/index.js @@ -0,0 +1,12 @@ +import { combineReducers } from '@reduxjs/toolkit'; + +import { devicesReducer as devices } from './devices'; +import { positionsReducer as positions } from './positions'; + +export const rootReducer = combineReducers({ + devices, + positions, +}); + +export { devicesActions } from './devices'; +export { positionsActions } from './positions'; diff --git a/modern/src/store/modules/positions.js b/modern/src/store/modules/positions.js new file mode 100644 index 00000000..1df468cd --- /dev/null +++ b/modern/src/store/modules/positions.js @@ -0,0 +1,16 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const { reducer, actions } = createSlice({ + name: 'positions', + initialState: { + items: {}, + }, + reducers: { + update(state, action) { + action.payload.forEach(item => state.items[item['deviceId']] = item); + }, + } +}); + +export { actions as positionsActions }; +export { reducer as positionsReducer }; -- cgit v1.2.3