Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any suggestions on how can I improve rendering of 10k todos in redux powered react app #3342

Closed
ui-ninja opened this issue Jan 28, 2019 · 3 comments

Comments

@ui-ninja
Copy link

Any suggestions are welcome for below issue.

Problem statement

I'm printing 10,000 rows of todos with toggle button. There are two issues with this:

  1. Initial render too slow.
  2. When clicked on toggle button, it takes nearly 2 secs to toggle (via Performance tab of Chrome dev tool)

Codesanbox link https://codesandbox.io/s/pz583w6zm

import React, { PureComponent } from "react";
import ReactDOM from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore } from "redux";
import "./styles.css";

function createCards() {
  return new Array(10000).fill(null).map((_, id) => ({
    id,
    name: `card ${id}`,
    done: id % 2
  }));
}

const rootReducer = (state = { cardIds: [] }, action) => {
  switch (action.type) {
    case "LOAD":
      const cards = createCards();
      return {
        cardsById: cards,
        cardIds: Object.keys(cards).map(i => cards[i].id)
      };
    case "TOGGLE": {
      const { id } = action;
      const card = state.cardsById[id];
      return {
        ...state,
        cardsById: {
          ...state.cardsById,
          [id]: {
            ...card,
            done: !card.done
          }
        }
      };
    }
    default:
      return state;
  }
};

const store = createStore(rootReducer);

const Card = ({ card, toggle }) => (
  <div
    className="card"
    style={{
      color: card.done ? "green" : "red"
    }}
  >
    <span className="title">{card.name}</span>
    <button onClick={() => toggle(card.id)}>Toggle</button>
  </div>
);
const ConnectedCard = connect(
  (state, ownProps) => {
    const { cardId } = ownProps;
    const card = state.cardsById[cardId];
    return { card };
  },
  dispatch => ({
    toggle: id => dispatch({ type: "TOGGLE", id })
  })
)(Card);

class CardList extends PureComponent {
  componentDidMount = () => this.props.load();
  render() {
    const { cardIds } = this.props;
    return (
      <div className="App">
        {cardIds &&
          cardIds.map(cardId => <ConnectedCard key={cardId} cardId={cardId} />)}
      </div>
    );
  }
}

const App = connect(
  state => {
    const cardIds = state.cardIds;
    return { cardIds };
  },
  dispatch => ({
    load: () => dispatch({ type: "LOAD" })
  })
)(CardList);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

@timdorr
Copy link
Member

timdorr commented Jan 28, 2019

This is a bug tracker, not a support system. For usage questions, please use Stack Overflow or Reactiflux where there are a lot more people ready to help you out. Thanks!

@timdorr timdorr closed this as completed Jan 28, 2019
@markerikson
Copy link
Contributor

Also, this is the wrong repo - that would be a React-Redux question.

Having said that, the snippets shown look like they're generally doing the right thing pattern-wise.

I'll link this to reduxjs/react-redux#1164 as a reminder for me to look at this later.

@ui-ninja
Copy link
Author

@timdorr My bad. Sorry!
@markerikson I will follow the given link. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants