javascript - ReactJS + Flux - Hur implementerar man toasts/aviseringar?
Jag försöker förstå Flux och Reactjs.
Tänk på följande mycket enkla scenario:
Du har ett formulär med få inmatningar. När användaren skickar in formuläret,
ActionCreator.publishAnnouncement(this.state.announcement);
kallas inuti min formulärkomponent. Så här ser publishAnnouncement-metoden ut:
var publishAnnouncement = function (announcement) {
AnnouncementAPI.publishAnnouncement(
announcement,
successCallback,
failureCallback
)
};
AnnouncementAPI är bara ett omslag runt ett AJAX HTTP POST-anrop. Det tar två återuppringningar - vid framgång och vid misslyckande.
Och nu: Jag behöver visa en notifikation/toast på skärmen - som indikerar framgång eller misslyckande. Hur skulle du göra det på ett Flux-sätt?
Jag funderade på att skapa en Notification-komponent och rendera den inne i mitt formulär. Som följande:
<Notification title={this.state.notification.title} message={this.state.notification.title} visible={this.state.notification.visibility} // ?? onTimeExceeded ?? />
Men hur hanterar jag dessa återuppringningar? Ska jag skapa NotificationStore som lyssnar på ANNOUNCEMENT_PUBLISHING_SUCCEEDED och ANNOUNCEMENT_PUBLISHING_FAILED händelser? Som en reaktion på dessa händelser, sänder store ett CHANGE-event och på så sätt uppdateras mitt Notification.
Men även om jag gör det, hur ska jag instruera min Notifikation att visa/dölja sig? Eller ännu värre, att dyka upp och försvinna efter 2 sekunder?
Jag har sett några komponenter på GitHub och var och en av dem använder refs osv, vilket jag personligen inte tycker om.
Sammanfattningsvis: Hur skulle du implementera detta? Eller kanske finns ett sådant projekt? Om så är fallet, var kan jag hitta det?
Svar #1
Jag ser inget fel med att ha en butik enbart för aviseringar, särskilt om du vill ha logik kring att visa/dölja aviseringar på timers, visa flera aviseringar, etc.
Det finns två sätt jag skulle överväga att skriva detta på:
Bind NotificationStore direkt till de success-/failure-callbacks du bryr dig om, som du nämnde i din fråga. Inte säker på vilken flux-implementation du använder, så det här blir lite som pseudokod.
class NotificationStore { constructor() { this.notificationId = 0; this.notifications = {}; this.bindActionType( CLEAR_NOTIFICATION, this.handleClearNotification ); this.bindActionType( ANNOUNCEMENT_PUBLISHING_SUCCEEDED, this.handleAnnouncementPublishingSucceeded ); // etc... } handleAnnouncementPublishingSucceeded(action) { this.addNotification("Success!", { timeout: 2000 }); } handleClearNotification(action) { this.removeNotification(action.notificationId); } addNotification(message, options) { const nextId = this.notificationId++; const notification = { message: message }; this.notifications[nextId] = notification; this.emit("change"); // if we specified a timeout, remove the notification // after the timeout expires. if (options.timeout) { setTimeout(() => { dispatch(CLEAR_NOTIFICATION, { notificationId: nextId }); }, options.timeout); } } removeNotification(notificationId) { delete this.notifications[nextId]; this.emit("change"); } }Ange de aviseringar du vill ha i dina action creators. Detta är mer explicit men mindre centraliserat.
var publishAnnouncement = function (announcement) { AnnouncementAPI.publishAnnouncement( announcement, (response) => { dispatch(ANNOUNCEMENT_PUBLISHING_SUCCEEDED, ...); dispatch(CREATE_NOTIFICATION, { message: "Success!", timeout: 2000 }); }, (error) => { dispatch(ANNOUNCEMENT_PUBLISHING_FAILED, ...); dispatch(CREATE_NOTIFICATION, { message: "Failure!" }); } ) };I det här fallet skulle NotificationStore se i princip likadan ut, men utan att binda till varje enskild success/fail-åtgärd. I båda fallen skulle jag ha en enda Notifications-widget nära toppen av min komponentträd som renderade listan med notifikationer.
Svar #2
Till försvar för refs (och som författare till den länkade GitHub-repot): Dina butiker skulle kunna avge ett event när de ändras, vilket skulle ha en handler i komponenten. Denna handler skulle sedan utlösa notisen via ref. Det är mycket mindre komplext att låta din komponent hantera notisen genom refs istället för props.
