Tworzę i nasłuchuję normalnych DOM CustomEvent
do komunikacji z węzłami nadrzędnymi:
U dziecka:
var moveEvent = new CustomEvent('the-graph-group-move', {
detail: {
nodes: this.props.nodes,
x: deltaX,
y: deltaY
},
bubbles: true
});
this.getDOMNode().dispatchEvent(moveEvent);
W rodzicu:
componentDidMount: function () {
this.getDOMNode().addEventListener("the-graph-group-move", this.moveGroup);
},
To działa, ale czy istnieje sposób specyficzny dla React, który byłby lepszy?
<Child onCustomEvent={this.handleCustomEvent} />
. W Reakcie nie ma obsługi niestandardowych zdarzeń z bąbelkami.Odpowiedzi:
Jak wspomniano wyżej:
Abstrakcja programowania reaktywnego jest ortogonalna:
Zamiast tego, filozofia React opiera się na wzorcu Command:
Bibliografia
źródło
a class of debugging problems where you don't know what triggers some code because of a long chain of events triggering other events
. Wzór polecenia z jednokierunkowego przepływu danych są React filozofię.możesz napisać prostą usługę, a następnie z niej skorzystać
/** eventsService */ module.exports = { callbacks: {}, /** * @param {string} eventName * @param {*} data */ triggerEvent(eventName, data = null) { if (this.callbacks[eventName]) { Object.keys(this.callbacks[eventName]).forEach((id) => { this.callbacks[eventName][id](data); }); } }, /** * @param {string} eventName name of event * @param {string} id callback identifier * @param {Function} callback */ listenEvent(eventName, id, callback) { this.callbacks[eventName][id] = callback; }, /** * @param {string} eventName name of event * @param {string} id callback identifier */ unlistenEvent(eventName, id) { delete this.callbacks[eventName][id]; }, };
przykład (to samo dotyczy wyzwalania)
import eventsService from '../../../../services/events'; export default class FooterMenu extends Component { componentWillMount() { eventsService .listenEvent('cart', 'footer', this.cartUpdatedListener.bind(this)); } componentWillUnmount() { eventsService .unlistenEvent('cart', 'footer'); } cartUpdatedListener() { console.log('cart updated'); } }
źródło
Zdarzenia można wyświetlać poprzez wywołania zwrotne przekazywane w kontekstach: [CodePen]
import * as React from 'react'; const MyEventContext = React.createContext(() => {}); const MyEventBubbleContext = ({children, onMyEvent}) => { const bubbleEvent = React.useContext(MyEventContext); const handleMyEvent = React.useCallback((...args) => { // stop propagation if handler returns false if (onMyEvent(...args) !== false) { // bubble the event bubbleEvent(...args); } }, [onMyEvent]); return ( <MyEventContext.Provider value={handleMyEvent}> {children} </MyEventContext.Provider> ); }; const MyComponent = () => ( <MyEventBubbleContext onMyEvent={e => console.log('grandparent got event: ', e)}> <MyEventBubbleContext onMyEvent={e => console.log('parent got event: ', e)}> <MyEventContext.Consumer> {onMyEvent => <button onClick={onMyEvent}>Click me</button>} </MyEventContext.Consumer> </MyEventBubbleContext> </MyEventBubbleContext> ); export default MyComponent;
źródło
Jest jeszcze jeden, który znalazłem, który jest całkiem rozsądny, zwłaszcza jeśli wiercenie otworów od rodzica do dziecka staje się już uciążliwe. Nazwał to mniej prostą komunikacją. Oto link:
https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md
źródło
Możliwe rozwiązanie, jeśli absolutnie musisz uciekać się do wzorca Observer w aplikacji ReactJs, możesz przejąć normalne zdarzenie. Na przykład, jeśli chcesz, aby klawisz delete powodował
<div>
zaznaczenie do usunięcia, możesz<div>
nasłuchiwać zdarzenia keydown, które zostanie wywołane przez zdarzenie customEvent. Uwięź keydown na ciele icustomEvent
wywołaj zdarzenie keydown na wybranym<div>
. Udostępnianie na wypadek, gdyby komuś pomogło.źródło
Magazyn centralny [Redux], który rozprowadza stan do klientów, a następnie stan „wysyłania” z powrotem do sklepu jest również wzorem obserwatora. Sposób na publikowanie / subskrybowanie tylko gorzej z powodu jawnego (kruchego?) Narzutu łączącego ścieżki rekwizytów / wydarzeń. Aby zhakować hierarchię, React zapewnia kontekst (wzorzec dostawcy) lub obserwowalne biblioteki, które śmierdzą. Podobnie jak MobX, który wprowadza nowe dekoratory @observable lub Vue, który wprowadza nową składnię szablonów „v-if”. Zdarzenia są i tak głównym sposobem działania pętli zdarzeń DOM i javascript, więc dlaczego nie? Myślę, że zrobili to sataniści. Lol
źródło
Zdaję sobie sprawę, że to pytanie jest już dość stare, ale ta odpowiedź może komuś pomóc. Napisałem pragmę JSX dla Reacta, która dodaje deklaratywne zdarzenie niestandardowe: jsx-native-events .
Zasadniczo po prostu używasz
onEvent<EventName>
wzorca do obserwowania wydarzeń.źródło