Quantcast
Channel: Krzysztof Żuraw blog's RSS Feed
Viewing all articles
Browse latest Browse all 205

Debouncing forms in React with Redux - part three

$
0
0

Hi! Welcome to the last part of blog series about debouncing forms in React. Today I want to show you how can you add redux to your debounced component.

Adding redux

It may seem like overkill for this simple example but I decided to add redux to show how this debounced form can be used in the more realistic scenario.

So, after adding redux and react-redux to my application I started by creating actions & actions creators under src/actions/index.js:

exportconstADD_WORD='ADD_WORD'exportconstaddWord=word=>({
  type:ADD_WORD,
  word,})

To explain how those two can be used I added a small test in ‘actions.test.js`:

import{ADD_WORD, addWord }from'./index'describe('Actions',()=>{it('should create action to add word',()=>{const expectedAction ={
      type:ADD_WORD,
      word:'fake',}expect(addWord('fake')).toEqual(expectedAction)})})

As you can see calling addWord with some string should dispatch action with ADD_WORD type and typed a word.

Next step was to add src/reducers/index.js:

import{ combineReducers }from'redux'import{ADD_WORD}from'../actions/index'exportconstwords=(state =[], action)=>{switch(action.type){caseADD_WORD:return[action.word,...state]default:return state
  }}const rootReducer =combineReducers({ words })exportdefault rootReducer

Where I have my pure function words which is getting its own piece of state to work with. In this case, I want my typed words to be first in a state of my application. I also added tests:

import{ words }from'./index'import{ADD_WORD}from'../actions/index'describe('Words reducer',()=>{it('should return initial state',()=>{expect(words(undefined,{})).toEqual([])})it('should handle ADD_WORD on initial state',()=>{expect(words([],{ type:ADD_WORD, word:'tom'})).toEqual(['tom'])})it('should handle ADD_WORD on existing state',()=>{expect(words(['tim'],{ type:ADD_WORD, word:'tom'})).toEqual(['tom','tim',])})})

The last thing is to set up my store and connect it with react application. The first step is happening in store.js:

import{ createStore, compose }from'redux'import rootReducer from'./reducers'const store =createStore(
  rootReducer,compose(window.devToolsExtension ? window.devToolsExtension():f=> f))exportdefault store

I create here my store with rootReducer which in this case is just only words reducer and I also added redux dev tools which help me debug my redux code.

The second step is to modify my index.js so redux can be injected into my application:

import{ Provider }from'react-redux'import AppContainer from'./components/App/AppContainer'import store from'./store'const root =(<Provider store={store}><AppContainer /></Provider>)
ReactDOM.render(root, document.getElementById('root'))

Using redux with react applications

You may notice that Provider component is wrapping a new one - AppContainer. This is a nice pattern to use when using redux & react applications. It boils down to two concepts: component and container. A component is responsible only for rendering html. A container is a way to get your data from the redux store.

That’s why I created AppContainer:

import React from'react'import{ connect }from'react-redux'import{ addWord }from'../../actions/index'import App from'./App'exportconstAppContainer=props=>(<App addWord={props.addWord} words={props.words}/>)constmapDispatchToProps=dispatch=>({addWord:word=>dispatch(addWord(word)),})constmapStateToProps=state=>({
  words: state.words,})exportdefaultconnect(mapStateToProps, mapDispatchToProps)(AppContainer)

Here I added two typical functions for react applications with redux - mapDispatchToProps& mapStateToProps. In the first one, I tell redux that when I call addWord inside my App component it should dispatch an action from actions/index. The second function is for extracting the data from the store - it will be the best if my component has only access to this part of a state which it is concerned about.

That’s all for today! To recap: I’ve added redux to my application and used Presentational and Container Components and I have my debounced input with react & redux!

Github repo can be found here.


Viewing all articles
Browse latest Browse all 205

Trending Articles