Использование прокси для прикрепления обратного вызова к объекту с помощью метода самонастройки - PullRequest
0 голосов
/ 23 сентября 2018

Я хочу создать прокси на объекте (экземпляр Counter ниже), который при изменении приведет к запуску всех функций массива callbacks (массив callbacks будет заполнен() => this.setState() из любого компонента React, использующего данные из экземпляра счетчика ... таким образом, повторный рендеринг будет запущен и отобразит новые данные).Одним из ограничений является то, что объектом манипулируют только изнутри себя (методы экземпляра increment и decrement).Другое ограничение заключается в том, что массив callbacks должен быть редактируемым даже после инициализации объекта и прокси-сервера (а затем запускается при каждом вызове методов экземпляра).Я пытаюсь использовать эту технику для повторного рендеринга компонента React, основанного на активности класса counter.Вот моя текущая попытка сделать это (не рендерится при увеличении или уменьшении).Большое спасибо, что нашли время, чтобы прочитать это, и я очень ценю любые советы или предложения!

import React, { Component } from 'react'

class Counter {

  count = 0

  increment = () => this.count++

  decrement = () => this.count--

}

const counter = new Counter()

const callbacks = []

const validator = {

  // recursively creates callback for any object change...
  // not only for top-level properties

  get(target, key) {
    return (
      typeof target[key] === 'object' &&
      target[key] !== null
    )
      ? new Proxy(target[key], validator)
      : target[key]
  },

  set() {
    callbacks.forEach((update) => update())
    return true
  },

}

const proxy = new Proxy({}, validator)

Object.assign(proxy, counter)

class CounterComponent extends Component {

  counter = {}

  constructor() {
    super()
    this.counter = counter
    callbacks.push(() => {
      this.setState({})
    })
  }

  render() {
    return (
      <div>
        <button
          children='-'
          onClick={ this.counter.decrement }
        />
        <span children={ this.counter.state.count } />
        <button
          children='+'
          onClick={ this.counter.increment }
        />
      </div>
    )
  }

}
...