Skip to content

Commit 9c6736d

Browse files
authored
chore(dev): replace Redux configuration with Redux Toolkit (#17)
1 parent c250d6c commit 9c6736d

File tree

9 files changed

+101
-197
lines changed

9 files changed

+101
-197
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ If your app requires authorization, you need to implement login, signup function
2020

2121
#### Redux
2222

23-
Redux can contain global state of the app. This is very useful but on the other hand, it takes time to setup if you are not familiar with it. In the boilerplate, you see [module file](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/modules/app.module.js) which contains actions, reducer and store in a file. To connect with actions and state from component, you need to call [connector](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/utils/connector.js). You can use actions and state from props. Here is an [example](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/routes/Routes.js#L10-L15). To combine reducer, first you can add another module file then import in connector like this [code](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/utils/connector.js#L41-L42). Lastly import module in [store](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/utils/store.js#L21) as well.
23+
We are using [Redux Toolkit](https://redux-toolkit.js.org/) to simplify the redux setup and minimize boilerplates.
24+
Redux can contain global state of the app. This is very useful but on the other hand, it takes time to setup if you are not familiar with it. In the boilerplate, you see [slices file](https://github.com/WataruMaeda/react-native-boilerplate/blob/master/src/slices/app.slice.js) which contains actions and reducers in a file. Please follow the [quick start tutorials](https://redux-toolkit.js.org/tutorials/quick-start) to see how store is setup; and how to use Redux state and actions in React Components.
2425

2526
#### Assets
2627

@@ -39,8 +40,8 @@ It's very important to keep code clean to maintain readability and productivity.
3940
- [expo](https://github.com/expo/expo)
4041
- [react-navigation 5.x](https://github.com/react-navigation/react-navigation)
4142
- [redux](https://github.com/reduxjs/redux)
43+
- [redux-toolkit](https://redux-toolkit.js.org/)
4244
- [redux-logger](https://github.com/LogRocket/redux-logger)
43-
- [redux-thunk](https://github.com/reduxjs/redux-thunk)
4445
- [moment](https://github.com/moment/moment)
4546
- [axios](https://github.com/axios/axios)
4647
- [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons)

babel.config.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
module.exports = function(api) {
2-
api.cache(true);
1+
module.exports = (api) => {
2+
api.cache(true)
33
return {
44
presets: ['babel-preset-expo'],
55
plugins: [
@@ -8,13 +8,13 @@ module.exports = function(api) {
88
{
99
alias: {
1010
components: './src/components',
11-
scenes: './src/scenes',
11+
scenes: './src/scenes',
1212
theme: './src/theme',
1313
utils: './src/utils',
14-
modules: './src/modules'
14+
slices: './src/slices',
1515
},
1616
},
1717
],
1818
],
19-
};
20-
};
19+
}
20+
}

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@react-navigation/drawer": "^5.11.4",
1717
"@react-navigation/native": "^5.8.10",
1818
"@react-navigation/stack": "^5.12.8",
19+
"@reduxjs/toolkit": "^1.5.1",
1920
"axios": "^0.21.1",
2021
"expo": "^41.0.0",
2122
"expo-asset": "~8.3.1",
@@ -37,9 +38,7 @@
3738
"react-native-web": "~0.13.12",
3839
"react-redux": "^7.1.1",
3940
"redux": "^4.0.4",
40-
"redux-logger": "^3.0.6",
41-
"redux-promise-middleware": "^6.1.1",
42-
"redux-thunk": "^2.3.0"
41+
"redux-logger": "^3.0.6"
4342
},
4443
"devDependencies": {
4544
"babel-eslint": "^10.1.0",

src/modules/app.module.js

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/routes/Routes.js

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import React, { useEffect } from 'react'
2-
import PropTypes from 'prop-types'
32
import { Text } from 'react-native'
4-
import Connector from 'utils/connector'
3+
import { useSelector, useDispatch } from 'react-redux'
4+
import { authenticate } from 'slices/app.slice'
55
import Main from './navigation'
66

7-
const Routes = ({ actions, checked, loggedIn }) => {
7+
const Routes = () => {
8+
const { checked, loggedIn } = useSelector((state) => state.app)
9+
const dispatch = useDispatch()
10+
811
useEffect(() => {
9-
actions.authenticate()
12+
dispatch(authenticate({ loggedIn: true, checked: true }))
1013
}, [])
1114

1215
// TODO: switch router by loggedIn state
@@ -17,26 +20,4 @@ const Routes = ({ actions, checked, loggedIn }) => {
1720
return <Main />
1821
}
1922

20-
Routes.propTypes = {
21-
actions: PropTypes.shape({
22-
authenticate: PropTypes.func,
23-
}),
24-
checked: PropTypes.bool,
25-
loggedIn: PropTypes.bool,
26-
}
27-
28-
Routes.defaultProps = {
29-
actions: {
30-
authenticate: () => null,
31-
},
32-
checked: false,
33-
loggedIn: false,
34-
}
35-
36-
export default (props) => (
37-
<Connector>
38-
{({ actions, state: { app } }) => (
39-
<Routes actions={actions.app} {...app} {...props} />
40-
)}
41-
</Connector>
42-
)
23+
export default Routes

src/slices/app.slice.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* eslint-disable no-param-reassign */
2+
import { createSlice } from '@reduxjs/toolkit'
3+
4+
// ------------------------------------
5+
// Constants
6+
// ------------------------------------
7+
8+
const initialState = {
9+
checked: false,
10+
loggedIn: false,
11+
me: {},
12+
}
13+
14+
// ------------------------------------
15+
// Slice
16+
// ------------------------------------
17+
18+
const appSlice = createSlice({
19+
name: 'app',
20+
initialState,
21+
reducers: {
22+
authenticate: (state, { payload }) => {
23+
state.loggedIn = payload.loggedIn
24+
state.checked = payload.checked
25+
},
26+
saveMe: (state, { payload }) => {
27+
state.me = payload.me
28+
},
29+
},
30+
})
31+
32+
export const { action } = appSlice
33+
export const { authenticate, saveMe } = appSlice.actions
34+
35+
export default appSlice.reducer

src/utils/connector.js

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/utils/store.js

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,25 @@
11
import {
2-
createStore, applyMiddleware, compose, combineReducers,
3-
} from 'redux'
4-
import thunk from 'redux-thunk'
2+
configureStore,
3+
combineReducers,
4+
getDefaultMiddleware,
5+
} from '@reduxjs/toolkit'
56
import logger from 'redux-logger'
6-
import app from 'modules/app.module'
7+
import appReducer from 'slices/app.slice'
78

8-
const analytics = () => (next) => (action) => {
9-
window.dataLayer = window.dataLayer || []
10-
window.dataLayer.push({
11-
event: action.type,
12-
payload: action.payload,
13-
})
9+
const rootReducer = combineReducers({
10+
app: appReducer,
11+
// add more reducers
12+
})
1413

15-
return next(action)
16-
}
14+
const defaultMiddleware = getDefaultMiddleware({
15+
serializableCheck: false,
16+
immutableCheck: false,
17+
})
1718

18-
// Redux store config
19-
const configureStore = (initialState = {}) => {
20-
const reducers = combineReducers({
21-
app,
22-
})
23-
24-
// Middleware and store enhancers
25-
const middlewares = [
26-
thunk,
27-
process.env.NODE_ENV !== 'production' && logger,
28-
analytics,
29-
].filter(Boolean)
30-
const enhancer = compose(applyMiddleware(...middlewares))
31-
const store = createStore(reducers, initialState, enhancer)
32-
33-
return store
34-
}
35-
36-
const store = configureStore()
19+
const store = configureStore({
20+
reducer: rootReducer,
21+
// eslint-disable-next-line no-undef
22+
middleware: __DEV__ ? defaultMiddleware.concat(logger) : defaultMiddleware,
23+
})
3724

3825
export default store

yarn.lock

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,13 @@
16961696
dependencies:
16971697
regenerator-runtime "^0.13.4"
16981698

1699+
"@babel/runtime@^7.9.2":
1700+
version "7.14.0"
1701+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
1702+
integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
1703+
dependencies:
1704+
regenerator-runtime "^0.13.4"
1705+
16991706
"@babel/template@^7.0.0", "@babel/template@^7.10.4", "@babel/template@^7.3.3", "@babel/template@^7.8.6":
17001707
version "7.10.4"
17011708
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@@ -3537,6 +3544,16 @@
35373544
color "^3.1.3"
35383545
react-native-iphone-x-helper "^1.3.0"
35393546

3547+
"@reduxjs/toolkit@^1.5.1":
3548+
version "1.5.1"
3549+
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.5.1.tgz#05daa2f6eebc70dc18cd98a90421fab7fa565dc5"
3550+
integrity sha512-PngZKuwVZsd+mimnmhiOQzoD0FiMjqVks6ituO1//Ft5UEX5Ca9of13NEjo//pU22Jk7z/mdXVsmDfgsig1osA==
3551+
dependencies:
3552+
immer "^8.0.1"
3553+
redux "^4.0.0"
3554+
redux-thunk "^2.3.0"
3555+
reselect "^4.0.0"
3556+
35403557
"@segment/loosely-validate-event@^2.0.0":
35413558
version "2.0.0"
35423559
resolved "https://registry.yarnpkg.com/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz#87dfc979e5b4e7b82c5f1d8b722dfd5d77644681"
@@ -9329,6 +9346,11 @@ [email protected]:
93299346
resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
93309347
integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==
93319348

9349+
immer@^8.0.1:
9350+
version "8.0.4"
9351+
resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.4.tgz#3a21605a4e2dded852fb2afd208ad50969737b7a"
9352+
integrity sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ==
9353+
93329354
import-fresh@^2.0.0:
93339355
version "2.0.0"
93349356
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
@@ -14335,16 +14357,18 @@ redux-logger@^3.0.6:
1433514357
dependencies:
1433614358
deep-diff "^0.3.5"
1433714359

14338-
redux-promise-middleware@^6.1.1:
14339-
version "6.1.2"
14340-
resolved "https://registry.yarnpkg.com/redux-promise-middleware/-/redux-promise-middleware-6.1.2.tgz#1c14222686934be243cbb292e348ef7d5b20d6d2"
14341-
integrity sha512-ZqZu/nnSzGgwTtNbGoGVontpk7LjTOv0kigtt3CcgXI9gpq+8WlfXTXRZD0WTD5yaohRq0q2nYmJXSTjwXs83Q==
14342-
1434314360
redux-thunk@^2.3.0:
1434414361
version "2.3.0"
1434514362
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
1434614363
integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
1434714364

14365+
redux@^4.0.0:
14366+
version "4.1.0"
14367+
resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4"
14368+
integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==
14369+
dependencies:
14370+
"@babel/runtime" "^7.9.2"
14371+
1434814372
redux@^4.0.4:
1434914373
version "4.0.5"
1435014374
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"

0 commit comments

Comments
 (0)