ReactEx

by evgkch

HTML

<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="root"></div>

SCSS

#root {
  display: flex;
  
  .element {
    margin: 10px;
    width: 100px;
    height: 100px;
    justify-content: center;
    align-items: center;
    background-color: blue;
  }
}

Babel + JSX

// Local store
class Store {
	constructor(name, initialState = {}) {
  	this.name = name;
    this.subscribers = [];
  	this.state = initialState;
  }
  subscribe(subscriber) {
  	this.subscribers.push(subscriber);
		console.log('subscribed');
		console.log(this);
  }
  unsubscribe(subscriber) {
  	this.subscribers = this.subscribers.filter(item => item !== subscriber);
		console.log('unsubscribed');
		console.log(this);
  }
  update(state) {
		if (typeof state === 'object') {
			this.state = { ...this.state, ...state };
	    this.subscribers.forEach(component => component.setState(this.state));
			console.log('updated');
			console.log(this);
	 	}
	}
};

// Subscribe component to store with controller
const connect = ({ store, controller, component, streamers = [] }) =>
	class extends React.Component {
    constructor() {
      super();
      this.ctrl = controller(
        (state) => store
          ? store.update(state)
          : this.setState(state),
        () => this.state
      );
			let buffer = store.state;
			console.log(store);
			if (store) store.subscribe(this);
			if (streamers) {
				streamers.forEach(streamer => {
					buffer = { ...streamer.state, ...buffer };
					streamer.subscribe(this);
				});
			}
			this.state = buffer;
    }
    componentDidMount() {
    	if (store) {
				this.setState(store.state);
			}
    }
    componentWillUnmount() {
    	if (store) store.unsubscribe(this);
			if (streamers) {
				streamers.forEach(streamer => {
					streamer.unsubscribe(this)
				});
			}
    }
    render() {
      return React.createElement(
        component,
        { ...this.state, ...this.props, ctrl: this.ctrl }
      );
    }
  };
  
  // Иммитация бэка
  class DataBase {
  	constructor(qty) {
    	// Массив объектов { key, value: 0 }
    	this.data = Array.from({ length: qty }, (v, k) => ({ key: k, value: 0 }));
    }
    getData() {
    	return this.handler({ data: this.data });
    }
    update(key) {
    	let value;
    	this.data =...