Redux: Input type text onChange that fires an action is slow

Created on 16 Jan 2016  路  12Comments  路  Source: reduxjs/redux

I have a reducer where the state object is big ( > 200 entries). I have an action that fires off whenever I change an input text component. To update the state I am doing an extend/assign on the state object with the new value inputed. This is very costly because the operation that operation is o(n) and I can feel it lagging whenever I type inside the input component. It seems like whenever there are many items in the state object this will happen. What are some ways to resolve this?

This is the reducer:

function timecardWeekItems(state, action){
  state = _.isUndefined(state) ? {} : state;
  switch (action.type){
    case TimecardAdminConstants.HOURS_ENTERED:
      var newState = _.assign({}, state);
      newState[action.uuid] = action.value;
      return newState;
    default:
      return state;
  }
}

I am using ES5 and underscore because we don't have babel yet.

question

Most helpful comment

Hi, @azin634. Do you mind elaborating on the finalized version of the solution you used to resolve your issue?

All 12 comments

Have you considered using Immutable.js? It might help with performance in the case when you often update objects with many keys.

Also are you convinced the perf problem is in the reducer? Have you profiled your React components?
See Advanced Performance.

It would also be immensely helpful if you could share a tiny project reproducing the issue.

I think it might be react rerendering when it doesn't need to.
I have a datastructure similar to this:

cart = {
  items: [0,1,2]
}

items = {
  0 : { date: "1/24", hours: ["1","2","3"] }
  1 : { date: "1/25", hours: ["1","2","3"] }
  2 : { date: "1/26" hours: ["1","2","3"] }
}

Each index of hours array are mapped to input text components. Whenever I type something to update the datastructure, this connect or mapStateToProps function gets called


function(state, ownProps){
  var items = _.map(ownProps.items, function(i){
    return state.items[i]
  })

  return {
    items: items
  }
}

Since _.map returns a new array, I think react will update every item. Correct me if I'm wrong. If I have 200 items, each has ~7 input text components, 1400 input components are updating.

Am I supposed to join the data in the mapStateToProps?
Should I restructure the data or would reselect help?

Can you please publish a tiny project demonstrating the issue?

The link in https://github.com/rackt/redux/issues/1244#issuecomment-172125612, to advanced performance is broken.
@azin634 One way to tackle this is to debounce the action dispatch in the text inputs onChange.

@tryggvigy Thanks, link is fixed now.

The problem to my issue is not related to redux being slow but react rendering. I have fixed it by using immutablejs. Closing issue.

Hi, @azin634. Do you mind elaborating on the finalized version of the solution you used to resolve your issue?

I have a similar problem. And it seems to be a rendering issue as well. However, isn't React, especially when used with Redux, supposed to solve this kind of rendering issue - by not calling the render function when the state doesn't change and by using the virtual dom?

@ConAntonakos wow sorry for the really late reply. I fixed it by using immutableJS and adding logic in shouldComponentUpdate.

@carpben it depends on the data structure you designed. If the component thinks its new data it will rerender. My problem was related to nesting data.

@carpben React does solve this type of issue, but not for free and it's easy to get it wrong. https://www.toptal.com/react/react-redux-and-immutablejs is a good read

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rui-ktei picture rui-ktei  路  3Comments

jbri7357 picture jbri7357  路  3Comments

elado picture elado  路  3Comments

cloudfroster picture cloudfroster  路  3Comments

mickeyreiss-visor picture mickeyreiss-visor  路  3Comments