-
Notifications
You must be signed in to change notification settings - Fork 0
Redux store
This boilerplate use Redux-Toolkit
and RTKQuery
to deal with business side.
We use them because they are often used by the community, very trendy and easy to debug.
RTKQuery
is a powerful data fetching and caching tool.
So we using it for asynchronous api calls.
Redux-Toolkit
is intended to be the standard way to write Redux logic.
So we using it for synchronous operations.
For the RTKQuery side, all is located in Services
.
You will find api.js
file that contains the declaration of the
fetchBaseQuery
customized with an interceptor
and the createApi
with the fetchBaseQuery
and empty endpoints.
import { Config } from '@/Config'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
const baseQuery = fetchBaseQuery({ baseUrl: Config.API_URL })
const baseQueryWithInterceptor = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// here you can deal with 401 error
}
return result
}
export const api = createApi({
baseQuery: baseQueryWithInterceptor,
endpoints: () => ({}),
})
Next to the Services/api.js
file you have a modules
folder. Each module
corresponds to an entity type and will inject endpoints
into the exported api
const of Services/api.js
For example , here are the user services :
import { api } from '../../api'
import fetchOne from './fetchOne'
export const userApi = api.injectEndpoints({
endpoints: build => ({
fetchOne: fetchOne(build), // Code split of the service api call
// You can add endpoints here
}),
overrideExisting: false,
})
export const { useLazyFetchOneQuery } = userApi
// |-- generated query which will be used in Containers
export default build => build.query({
query: id => `/users/${id}`,
})
Then in your containers it could be use like this :
import React, { useState, useEffect } from 'react'
import { View, TextInput } from 'react-native'
import { useLazyFetchOneQuery } from '@/Services/modules/users' // Import the query
const ExampleContainer = () => {
const [userId, setUserId] = useState('9')
const [
fetchOne,
{ data, isSuccess, isLoading, isFetching, error },
] = useLazyFetchOneQuery() // use the query
useEffect(() => {
fetchOne(userId)
}, [fetchOne, userId])
return (
<View>
<TextInput
onChangeText={setUserId}
editable={!isLoading}
keyboardType={'number-pad'}
maxLength={1}
value={userId}
/>
</View>
)
}
export default ExampleContainer
The RTKQuery is linked to the redux store in order to make it work and be debuggable with Flipper.
:::info See the API usage for more information :::
On the redux-toolkit side, we use it to configure all the store and save the default theme of the application.
For example, the storing of the favorite theme of the user
import { createSlice } from '@reduxjs/toolkit'
const slice = createSlice({
name: 'theme',
initialState: { theme: null, darkMode: null },
reducers: {
changeTheme: (state, { payload: { theme, darkMode } }) => {
if (typeof theme !== 'undefined') {
state.theme = theme
}
if (typeof darkMode !== 'undefined') {
state.darkMode = darkMode
}
},
setDefaultTheme: (state, { payload: { theme, darkMode } }) => {
if (!state.theme) {
state.theme = theme
state.darkMode = darkMode
}
},
},
})
export const { changeTheme, setDefaultTheme } = slice.actions
// |-------------|-- Generated actions which will be used in Containers
export default slice.reducer
:::info See the API usage for more information :::