React-Redux tips

Xena Coder
2 min readDec 11, 2020

--

If you are reading this article, you might have been familiar with Redux and have used it with React. But what if I give you some useful hints to feel more comfortable with this stack.

Avoid having one reducer

It’s not bad if an application is small. But when it goes to build a more complex business app, better to opt in forcombineReducers(reducer) solution.
Modify store.js file.

import { createStore, combineReducers } from 'redux'import { user } from './modules/user/user.reducer.js'
import { product } from './modules/user/product.reducer.js'
import { account } from './modules/user/account.reducer.js'
export const store = createStore(combineReducers({ user, product, account }))

Pros?
- make reducers readable;
- make your application structured;
- facilitate the testing;

Proxy access to the state

Once you place reducers in the functional module, you can access the state using selector. It’s a function that takes a state as a parameter and returns information (only the props needed for a component).

export const getProduct = productId => ({ product: { list } }) =>
list.find(product => product.id === productId)

// MyComponent.js
const MyComponent = () => {
const product = useSelector(getProduct(12))
return <div>{product.name}</div>
}

Prefix the name of your actions

Actions are written in uppercase letters separated by ‘_’ (ex. SET_USERS).

app/
modules/
user/
components/
user.actions.js <--- a place where all action creators are exported
user.reducer.js
user.selectors.js

Always test your reducers

As you know, reducers hold business of your application and manipulate the state. A reducer is a single function that takes 2 parameters so the code is easy to test.
Here is an example of a simple test using Jest:

describe('ReducerName', () => {
beforeEach(() => {
// Init a new state
})
describe('ACTION', () => {
// Group tests by action type
it('should test action with some params', () => {})
it('should test action with other params', () => {})
})
describe('SECOND_ACTION', () => {
it('should test action with some params', () => {})
})
})

Use custom middlewares

The most common example is handling HTTP calls during an action that uses redux-thunk.

export const foo = () =>
fetch('https://example.com/api/foo')
.then(data => ({ type: 'FOO', data }))
.catch(error => {
// Do something
})

export const bar = () =>
fetch('https://example.com/api/bar')
.then(data => ({ type: 'BAR', data }))
.catch(error => {
// Do something
})

These two functions are actually the same thing so we can refactor it. First, we need to define a middleware that would take care of this behavior.

const http = store => next => async action => {
if (action.http) {
try {
action.result = await fetch(action.http)
} catch (error) {
// Do something
}
}
return next(action)
}

// in redux store init
const exampleApp = combineReducers(reducers)
const store = createStore(exampleApp, applyMiddleware(http))

These actions can be implemented in a much simpler way avoiding code duplication.

export const foo = () => ({ type: 'FOO', http: 'https://example.com/api/foo' })

export const bar = () => ({ type: 'BAR', http: 'https://example.com/api/bar' })

Conclusion

For extra info go there -> https://redux.js.org/introduction/getting-started

--

--

Xena Coder
Xena Coder

Written by Xena Coder

Frontend developer. Master of Sports in Powerlifting and Weightlifting

No responses yet