Mam składnik z detektorami zdarzeń „mouseover” i „mouseout”. Kilka z tych samych komponentów renderuje się obok siebie (lub nakładają się) w przeglądarce, więc możliwe jest uruchomienie zdarzenia „mouseover”, „mouseout”, a następnie innego zdarzenia „mouseover” w tej kolejności (jeśli najeżdżasz od jednego elementu do następnego).

Komponent ustawia stan we wszystkich tych instancjach, ale zastanawiam się, czy nie ma bardziej wydajnego sposobu na to, aby uniknąć trzech aktualizacji stanu, które następują jedna po drugiej.

Czy próbuję tutaj niepotrzebnie optymalizować, czy jest to uzasadniona obawa? Oto przykład tego, co mam na myśli. W tym przypadku po prostu aktualizuję licznik, ale załóżmy, że robię coś droższego, na przykład iterację po tablicy.

(Zastrzeżenie, nie użyłem tutaj nowego wstawiania kodu i mam problem z uruchomieniem tego fragmentu).

import React, { Component } from 'react';

class DummyComponent extends Component {
  state = {
    someProp: 1
  };
  
  componentDidMount() {
    this.addEventListener('mouseover', this.handleEvent);
    this.addEventListener('mouseout', this.handleEvent);
  }
  
  componentWillUnmount() {
    this.removeEventListener('mouseover', this.handleEvent);
    this.removeEventListener('mouseout', this.handleEvent);
  }
  
  handleEvent(event) {
    console.log(event.type);
    this.setState({ someProp: this.state.someProp += 1 });
  };
  
  render() {
    return (
      <section>
        {this.state.someProp}
      </section>
    )
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
0
Jose 5 grudzień 2018, 07:53

1 odpowiedź

Najlepsza odpowiedź

Czy konieczne jest natychmiastowe załatwienie zdarzenia? Jeśli nie, wydaje się, że jest to dobry przypadek użycia do odrzucenia metody obsługi, aby nie była wywoływana częściej niż X milisekund (np. 100 ms). Wadą tego jest to, że program obsługi będzie czekał przynajmniej tak długo przed pierwszym uruchomieniem.

Biblioteka Lodash zapewnia implementację debounce.

Poniżej przedstawiamy, jak można zmodyfikować Twój kod, aby z niego korzystać:

import React, { Component } from 'react';
import _ from 'lodash';

class DummyComponent extends Component {
  state = {
    someProp: 1
  };

  componentDidMount() {
    this.addEventListener('mouseover', this.debouncedHandleEvent);
    this.addEventListener('mouseout', this.debouncedHandleEvent);
  }

  componentWillUnmount() {
    this.removeEventListener('mouseover', this.debouncedHandleEvent);
    this.removeEventListener('mouseout', this.debouncedHandleEvent);
  }

  handleEvent(event) {
    console.log(event.type);
    this.setState({ someProp: this.state.someProp += 1 });
  };

  // Debounced handler with a wait time of 100ms
  debouncedHandleEvent = _.debounce(handleEvent, 100)

  render() {
    return (
      <section>
        {this.state.someProp}
      </section>
    )
  }
}
1
Daniel Bank 5 grudzień 2018, 08:32