How to quickly render> 10,000 elements with React + Flux?

I would like to ask what is the correct way to quickly render> 10,000 elements in React.

Suppose I want to make a checkboxList that contains more dynamic elements of 10000 .

I am creating a repository that contains all the elements and it will be used as the state of the checkbox list.

When I click on any element of the checkbox, it updates the corresponding element by action and, therefore, the repository will be changed.

Since the repository has been changed, it causes the list of flags to be updated.

The list of flags updates its status and rendering.

The problem here is that if I click on any element of a flag, I need to wait> 3 seconds to mark this flag. I do not expect this because only one checkbox element needs to be redone.

I am trying to find the root cause. The most time-consuming part is inside the method of rendering the list of checkboxes associated with the .map that create the Checkbox component to form a list of components .. But in fact, only 1 checkbox should be re-rendered.

Below are my codes. I am using ReFlux for stream architecture.

Checkboxlististore

The store saves all items in the form of a map. (name as key, state (true / false) as value)

const Reflux = require('reflux');
const Immutable = require('immutable');
const checkboxListAction = require('./CheckboxListAction');

let storage = Immutable.OrderedMap();
const CheckboxListStore = Reflux.createStore({
	listenables: checkboxListAction,
	onCreate: function (name) {
		if (!storage.has(name)) {
			storage = storage.set(name, false);
			this.trigger(storage);
		}
	},
	onCheck: function (name) {
		if (storage.has(name)) {
			storage = storage.set(name, true);
			this.trigger(storage);
		}
	},
	onUncheck: function (name) {
		if (storage.has(name)) {
			storage = storage.set(name, false);
			this.trigger(storage);
		}
	},
	getStorage: function () {
		return storage;
	}
});

module.exports = CheckboxListStore;
Run codeHide result

Checkboxlististction

Action, creating, checking and unchecking any element of the flag with the provided name.

const Reflux = require('reflux');
const CheckboxListAction = Reflux.createActions([
	'create',
	'check',
	'uncheck'
]);
module.exports = CheckboxListAction;
Run codeHide result

Checkboxoxist

const React = require('react');
const Reflux = require('reflux');
const $ = require('jquery');
const CheckboxItem = require('./CheckboxItem');
const checkboxListAction = require('./CheckboxListAction');
const checkboxListStore = require('./CheckboxListStore');
const CheckboxList = React.createClass({
	mixins: [Reflux.listenTo(checkboxListStore, 'onStoreChange')],
	getInitialState: function () {
		return {
			storage: checkboxListStore.getStorage()
		};
	},
	render: function () {
		const {storage} = this.state;
		const LiComponents = storage.map((state, name) => {
			return (
				<li key = {name}>
					<CheckboxItem name = {name} />
				</li>
			);
		}).toArray();
		return (
			<div className = 'checkbox-list'>
				<div>
					CheckBox List
				</div>
				<ul>
					{LiComponents}
				</ul>
			</div>
		);
	},
	onStoreChange: function (storage) {
		this.setState({storage: storage});
	}
});

module.exports = CheckboxList;
Run codeHide result

CheckboxItem onChange .

const React = require('react');
const Reflux = require('reflux');
const $ = require('jquery');
const checkboxListAction = require('./CheckboxListAction');
const checkboxListStore = require('./CheckboxListStore');

const CheckboxItem = React.createClass({
	mixins: [Reflux.listenTo(checkboxListStore, 'onStoreChange')],
	propTypes: {
		name: React.PropTypes.string.isRequired
	},
	getInitialState: function () {
		const {name} = this.props;
		return {
			checked: checkboxListStore.getStorage().get(name)
		};
	},
	onStoreChange: function (storage) {
		const {name} = this.props;
		this.setState({
			checked: storage.get(name)
		});
	},
	render: function () {
		const {name} = this.props;
		const {checked} = this.state;
		return (
			<div className = 'checkbox' style = {{background: checked ? 'green' : 'white'}} >
				<span>{name}</span>
				<input ref = 'checkboxElement' type = 'checkbox'
					onChange = {this.handleChange}
					checked = {checked}/>
			</div>
		);
	},
	handleChange: function () {
		const {name} = this.props;
		const checked = $(this.refs.checkboxElement).is(':checked');
		if (checked) {
			checkboxListAction.check(name);
		} else {
			checkboxListAction.uncheck(name);
		}
	}
});

module.exports = CheckboxItem;
Hide result
+4
5

, Mobservable. , 10.000 , , . . blog .

+1

, :

  • 10 000 - (+ ) ( , ), - , , , div , , , . 100 000 , , . , . : http://react.rocks/tag/InfiniteScroll
  • - - storage.toArray().map(...) ( ) , , storage.forEach(...) push - . React diff - 10000 , , , .
  • - , 1 , chechbox. React ( CheckboxListChunks) . , , PureComponent componentShouldUpdate (, Reflux ?).
  • , ImmutableJS, , (, , ).
  • toComponentUpdate CheckboxList:

    shouldComponentUpdate:function(nextProps, nextState) {
        var storage = this.state.storage;
        var nextStorage = nextState.storage;
        if (storage.size !== nextStorage.size) return true;
        // check item names match for each index:
        return !storage.keySeq().equals(nextStorage.keySeq());
    }
    
+2

, :

  • JSX
  • a (jQuery?) .toArray()
  • .

, - ?

render: function () {
  return (
    <div className = 'checkbox-list'>
      <div>
        CheckBox List
      </div>
      <ul>
        {this.state.storage.map((state, name) => {
          return (
            <li key = {name}>
              <CheckboxItem name = {name} />
            </li>
          );
         })}
      </ul>
    </div>
  );
},
0

, / ?

, . checkedList [name1, name2...] CheckboxList , / . , Action.save() .
, / , -_-.

0

Source: https://habr.com/ru/post/1617753/


All Articles