Demystifying 15 lesser-known React Redux terms and features (With examples) 🔮
Tags: react, redux, webdev, javascript
Published: 2020-04-16 13:54:48

<center>_NOTE: Most of the content is regarding [React-Redux](https://react-redux.js.org/)._</center>

[Previously](https://dev.to/vaibhavkhulbe/hello-test-55l1), we talked about some of the major terms or features of React which may go unnoticed as we build or work on more and more project with the awesome UI library. 

As we make more and more big or complex applications with React, we come to know that handling the overall state of the entire app isn't possible with just [`React.Component`](https://reactjs.org/docs/react-component.html) class, using a [`constructor()`](https://reactjs.org/docs/react-component.html#constructor) with [`setState()`](https://reactjs.org/docs/react-component.html#setstate) call. We need a state container like the famous **[`Redux`](https://redux.js.org/)** to run it in different environments, centralizing the app state/logic and is easily debuggable.

So just like before, here are some more terms or features of Redux which you might have used but didn't quite know what or how exactly they do...and yes, _with examples_!

---

![Mystery GIF](https://media.giphy.com/media/Tf93AGTvPW2a8DkeHW/giphy.gif)
<figcaption>Exaclty that!</figcaption>

---

| Here are all the 15 terms/features \(￣︶￣*\)) |
| ------------- |:-------------:| -----:|
| [Redux core principles](#Term 1)      
| [Compromises of using Redux over Flux](#Term 2)
| [Difference between `mapStateToProps` and `mapDispatchToProps`](#Term 3)
| [Dispatching action in the _reducer_](#Term 4)
| [Dispatching and action on load](#Term 5)
| [Reset the state](#Term 6)
| [Use of _@_ symbol in _connect_](#Term 7)
| [Difference between `context` and Redux](#Term 8)
| [AJAX in Redux](#Term 9)
| [Accesing Redux _store_](#Term 10)
| [Why use constants?](#Term 11)
| [Why we use `ownProps`?](#Term 12)
| [Differences between `call()` and `put()`](#Term 13)
| [Differences between _saga_ and _thunk_](#Term 14)
| [Set initial state](#Term 15)

---

### 1. What are the core principles of Redux? <a name="Term 1"></a> [(Doc 📃)](https://redux.js.org/introduction/three-principles#three-principles) X﹏X

Redux works on three core principles:

#### 1️⃣ Single source of truth

> This means that the state of your entire application is stored in a [_store_](https://redux.js.org/glossary#store) as an object tree.

It has some advantages like:

- A single state tree makes it easier to debug or inspect an application.
- It also enables you to persist your app's state in development, for a faster development cycle.
- This makes it easy to create universal or large-scale apps.

_Example:_

```javascript
// If you execute the following:
console.log(store.getState())

// You'll get this as a result:
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
```

#### 2️⃣ State is read-only

> The only way you change the state is by releasing an [_action_](https://redux.js.org/glossary#action).

Because all changes are centralized and happen one by one, there are no subtle race conditions to watch out for.

_Example:_

```javascript
// This is how you dispatch actions:
store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})
```

#### 3️⃣ Changes are made with pure functions

> You write [_reducers_](https://redux.js.org/understanding/thinking-in-redux/glossary#reducer) to specify how the state is transformed by _actions_.

Because reducers are just (pure) functions, you can control the order in which they are called, pass additional data, or even make reusable reducers.

_Example:_

```javascript
// Here's how to create pure functions/reducers
function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
const reducer = combineReducers({ visibilityFilter, todos })
const store = createStore(reducer)
```

### 2. How's Flux better when compared to Redux? <a name="Term 2"></a> ([Flux Doc 📃](https://facebook.github.io/flux/)) (。﹏。*)

_Flux is a pattern and Redux is a library._ But there are few compromises you need to make when using Redux:

1. **You will need to avoid mutations**: You can enforce this with packages like [`redux-immutable-state-invariant`](https://github.com/leoasis/redux-immutable-state-invariant#readme), [Immutable.js](https://github.com/immutable-js/immutable-js#immutable-collections-for-javascript) etc.

2. **You're going to have to carefully pick your packages**: Redux has extension points such as middleware and store enhancers, having a vast ecosystem of packages.

3. **There is no nice Flow integration yet**.

Here's a great article for those who want to know more about Flux and Redux:

{% medium https://medium.com/edge-coders/the-difference-between-flux-and-redux-71d31b118c1 %}


### 3. What is the difference between `mapStateToProps()` and `mapDispatchToProps()`? <a name="Term 3"></a> ┗( T﹏T )┛

#### > `mapStateToProps()` ([Doc 📃](https://react-redux.js.org/using-react-redux/connect-mapstate#defining-mapstatetoprops))

It is a utility which helps your component to get updated state (which is updated by some other components). This function should be passed as the first argument to [`connect`](https://react-redux.js.org/7.1/api/connect#connect) and will be called every time when the Redux store state changes. 

_Example:_

```javascript
// TodoList.js
function mapStateToProps(state) {
  const { todos } = state
  return { todoList: todos.allIds }
}

export default connect(mapStateToProps)(TodoList)
```
#### > `mapDispatchToProps()` ([Doc 📃](https://react-redux.js.org/api/connect#mapdispatchtoprops-object-dispatch-ownprops-object))

It is a utility which will help your component to fire an action event (dispatching action which may cause a change of application state). The component gets the `[dispatch](https://react-redux.js.org/api/connect#dispatch)` by default.

_Example:_

```javascript
import { addTodo, deleteTodo, toggleTodo } from './actionCreators'

const mapDispatchToProps = {
  addTodo,
  deleteTodo,
  toggleTodo
}

export default connect(
  null,
  mapDispatchToProps
)(TodoApp)
```

### 4. What if you dispatch an _action_ in the _reducer_? <a name="Term 4"></a> ~~>_<~~

This comes back from a popular Stackoverflow question embedded below. Always remember that:

> **Dispatching an action within a reducer is an anti-pattern.**

{% stackoverflow 36730793 %}

### 5. What about dispatching and _action_ on load? <a name="Term 5"></a> <( _ _ )>

Yes yes, you can dispatch an action in on load with [`componentDidMount()`](https://reactjs.org/docs/react-component.html#componentdidmount) method verifying the data in the [`render()`](https://reactjs.org/docs/react-component.html#render) method.

_Example:_

```javascript
class App extends Component {
  componentDidMount() {
    this.props.fetchData()
  }

  render() {
    return this.props.isLoaded
      ? <div>{'Loaded'}</div>
      : <div>{'Not Loaded'}</div>
  }
}

const mapStateToProps = (state) => ({
  isLoaded: state.isLoaded
})

const mapDispatchToProps = { fetchData }

export default connect(mapStateToProps, mapDispatchToProps)(App)
```

### 6. How to reset state in Redux? <a name="Term 6"></a> (≧﹏ ≦)

The best way is to use a _root reducer_ and handle the _action_ to _reducer_ generated by [`combineReducers()`](https://redux.js.org/api/combinereducers). If you want to know deeply how exactly it's done check out [this article](https://alligator.io/redux/reset-state-redux/).

_Example:_

```javascript
const appReducer = combineReducers({
  // Top-level reducers here
})

const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    state = undefined
  }

  return appReducer(state, action)
}
```

### 7. Why we use the at _(@)_ symbol in the Redux connect decorator? <a name="Term 7"></a> (≧﹏ ≦)

In JavaScript, the _@_ symbol is used to signify _decorators_. Learn more about them [here](https://www.sitepoint.com/javascript-decorators-what-they-are/). Basically you annotate or modify classes and properties with them. 

{% stackoverflow 32646920 %}

### 8. What is the difference between React `context` and React-Redux? <a name="Term 8"></a> (T_T)

#### > React `context` ([Doc 📃](https://reactjs.org/docs/context.html))

> Context provides a way to pass data through the component tree without having to pass _props_ down manually at every level.

Consider using it for a small-scale application whereas Redux provides this and much more deep and powerful state control internally.

#### > React-Redux ([Doc 📃](https://react-redux.js.org/)) 

> React-Redux is the official React binding for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update data.

### 9. How to make an AJAX request in Redux? <a name="Term 9"></a> (T_T)

[AJAX](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started) allows you to send asynchronous HTTP requests to submit or retrieve data from the server.

To do an AJAX call in Redux you can use the [`redux-thunk`](https://github.com/reduxjs/redux-thunk) middleware which allows you to define async actions.

_Example:_

```javascript
export function fetchAccount(id) {
  return dispatch => {
    dispatch(setLoadingAccountState()) // Show a loading spinner
    fetch(`/account/${id}`, (response) => {
      dispatch(doneFetchingAccount()) // Hide loading spinner
      if (response.status === 200) {
        dispatch(setAccount(response.json)) // Use a normal function to set the received state
      } else {
        dispatch(someError)
      }
    })
  }
}

function setAccount(data) {
 return { type: 'SET_Account', data: data }
}
```

### 10. What is the recommended way of accessing Redux _store_? <a name="Term 10"></a> 〒▽〒

The best way is to use the `connect()` function using [Higher Order Functions (HOCs)](https://eloquentjavascript.net/05_higher_order.html) pattern. This allows to map _state_ and _action_ creators to the component, and have them passed in automatically as the _store_ updates.

_Example:_

```javascript
// You can pass the context as an option to connect
export default connect(
  mapState,
  mapDispatch,
  null,
  { context: MyContext }
)(MyComponent)

// or, call connect as normal to start
const ConnectedComponent = connect(
  mapState,
  mapDispatch
)(MyComponent)

// Later, pass the custom context as a prop to the connected component
<ConnectedComponent context={MyContext} />
```

### 11. Why we use constants in Redux? <a name="Term 11"></a> ≧ ﹏ ≦

This is because they allow us to easily find all usages of a specific functionality across the project. Also, you won't get much [`ReferenceError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError) when you use constants.

_Example:_

```javascript
// In constants.js
export const ADD_TODO = 'ADD_TODO'
export const DELETE_TODO = 'DELETE_TODO'
export const EDIT_TODO = 'EDIT_TODO'

// In actions.js
import { ADD_TODO } from './actionTypes';

export function addTodo(text) {
  return { type: ADD_TODO, text }
}

// In reducer.js
import { ADD_TODO } from './actionTypes'

export default (state = [], action) => {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ];
    default:
      return state
  }
}
```

### 12. Why we use of `ownProps` ([Doc 📃](https://react-redux.js.org/using-react-redux/connect-mapstate#ownprops-optional)) in `mapStateToProps()` and `mapDispatchToProps()`? <a name="Term 12"></a> (；′⌒')

The `ownProps` is an optional parameter we add as the second argument in both `mapStateToProps()` or `mapDispatchToProps()`. You use this only if your component needs the data from its own _props_ to retrieve data from the store.

_Example:_

```javascript
// Todo.js
function mapStateToProps(state, ownProps) {
  const { visibilityFilter } = state
  const { id } = ownProps
  const todo = getTodoById(state, id)

  // component receives additionally:
  return { todo, visibilityFilter }
}

// Later, in your application, a parent component renders:
<ConnectedTodo id={123} />
// and your component receives props.id, props.todo, and props.visibilityFilter
```
As the doc says:

> You do not need to include values from `ownProps` in the object returned from `mapStateToProps`. `connect` will automatically merge those different _prop_ sources into a final set of _props_.

### 13. What are the differences between `call()` and `put()` in _redux-saga_? <a name="Term 13"></a> (┬┬﹏┬┬)

[`redux-saga`](https://redux-saga.js.org/) is a library that aims to make application side effects easier to manage, more efficient to execute, easy to test, and better at handling failures.

#### > `call()` ([Doc 📃](https://redux-saga.js.org/docs/api/#callfn-args))

In simple words, you use `call()` to create _effect_ description, which instructs middleware to call the promise. After which the middleware invokes the function and examines its result.

#### > `put()` ([Doc 📃](https://redux-saga.js.org/docs/api/#putaction))

Whereas the `put()` function creates an _effect_, which instructs middleware to dispatch an action to the store.

```javascript
function* fetchUserSaga(action) {
  // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.
  // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable
  const userData = yield call(api.fetchUser, action.userId)

  // Instructing middleware to dispatch corresponding action.
  yield put({
    type: 'FETCH_USER_SUCCESS',
    userData
  })
}
```

Hence, both `call()` and `put()` are effect creator functions. 


### 14. What are the differences between _redux-saga_ and _redux-thunk_? <a name="Term 14"></a> ╯︿╰

The [`Redux Thunk`](https://github.com/reduxjs/redux-thunk) middleware allows you to write _action_ creators that return a function instead of an _action_. The _thunk_ can be used to delay the dispatch of an _action_, or to dispatch only if a certain condition is met. 

- Thunk uses _Promises_ to deal with them, whereas Saga uses _Generators_.
- Thunk is _simple to use_ and Promises are familiar, Sagas/Generators are more powerful but _you will need to learn them_.

Here is a good post on how you can implement both of them: 

{% link https://dev.to/bnorbertjs/async-react-basics-with-redux-thunk--redux-saga-4af7 %}

### 15. How to set initial state in Redux? <a name="Term 15"></a> ::>_<::

There are two ways:

- First, use the [`createStore`](https://redux.js.org/api/createstore) method which accepts an optional [`preloadedState`](https://redux.js.org/api/createstore#arguments) value as its second argument.

_Example:_

```javascript
const rootReducer = combineReducers({
  todos: todos,
  visibilityFilter: visibilityFilter
})

const initialState = {
  todos: [{ id: 123, name: 'example', completed: false }]
}

const store = createStore(
  rootReducer,
  initialState
)
```

- Or by using explicit check inside the reducer.

_Example:_

```javascript
function myReducer(state = someDefaultValue, action)
```

---

I hope I've explained these 15 points in the right way. Did you know about them? Honestly, I never knew about _@_ symbol in Redux!

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">Oh no... Better hit up <a href="https://twitter.com/docsmsft?ref_src=twsrc%5Etfw">@docsmsft</a> for help: <a href="https://t.co/Gvjh0h4YTT">https://t.co/Gvjh0h4YTT</a><br><br>Image source: <a href="https://t.co/d9j3psc1g1">https://t.co/d9j3psc1g1</a><a href="https://twitter.com/hashtag/DevHumour?src=hash&amp;ref_src=twsrc%5Etfw">#DevHumour</a> <a href="https://twitter.com/hashtag/Developer?src=hash&amp;ref_src=twsrc%5Etfw">#Developer</a> <a href="https://twitter.com/hashtag/Programming?src=hash&amp;ref_src=twsrc%5Etfw">#Programming</a> <a href="https://t.co/8dvAr1f0hs">pic.twitter.com/8dvAr1f0hs</a></p>&mdash; Microsoft Developer UK (@msdevUK) <a href="https://twitter.com/msdevUK/status/1250464655623020545?ref_src=twsrc%5Etfw">April 15, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

#### [📫 Subscribe to my weekly developer newsletter 📫](https://mailchi.mp/f59beeac6b9b/devupdates)

##### PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, [here](https://medium.com/@vaibhavkhulbe)'s my Medium profile.