Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger Notification/Callback after reflux action execution

I recently used reflux in my project and here is a question puzzled me a lot.
As the reflux pattern, I call actions in my React components, and fetch remote data in my reflux store which are listening to the actions. And my components listen to the changing of data in store. For example get a list of items. So far it's fine.
But sometimes, I want a notification which can told me that the action has executed successfully.
For example, I have a UserStore, a UserActions and a LoginComponent which listen to UserStore. when users have input username and password and click a submit button, the LoginComponent call UserActions.login(), and I send login request in UserStore. When login succeed, UserStore gets user infos from the response.
In this time, I want to give an prompt in LoginComponent such as 'Login Success'. I have two ways to do it but I don't think either is good enough.

  1. Give a flag in the data of UserStore then trigger changing. LoginComponent gets this flag when UserStore trigger a data change event, and then prompt. Because the UserStore would trigger data change not only in login success but also in some other situations like fetching user infos from cookies or sessionStorage, LoginComponent has to add an if-else for this login success flag, if it is login success then prompt.
    I don't think it is a good pattern because that the flag is just for the prompt and NOT a real data like user's infos. And if I also want prompt after user change password, I will need another flag field.
  2. Pass a promise(or a callback function) to the UserAction call, and resolve this promise after login succeed, then the LoginComponent can prompt in promise.then. It's seem better than the first one, but isn't it a little anti-pattern because the promise which been passed through actions to stores may broke the Unidirectional in reflux?

What I want to ask is: What's the common/appropriate way to solve this problem?

I'm not from an English area and not good at English expression. This is my first question in stackoverflow.com. I'm not very sure if I have described my question clearly. So if you have some advice to me about the question, please let me know and I will improve it to help others who care about this question. Thanks a lot!

like image 362
Zhang Chao Avatar asked Nov 09 '22 23:11

Zhang Chao


1 Answers

You can include a parameter in the trigger.

export default class AppCtrl extends AppCtrlRender {
  constructor() {
    super();
    this.state = getState();
  }

  componentDidMount = () => { this.unsubscribe = BasicStore.listen(this.storeDidChange); }
  componentWillUnmount = () => { this.unsubscribe(); }
  storeDidChange = (id) => {
    switch (id) {
      case 'data1': this.setState({Data1: BasicStore.getData1()}); break;
      case 'data2': this.setState({Data2: BasicStore.getData2()}); break;
      case 'data3': this.setState({Data3: BasicStore.getData3()}); break;
      default: this.setState(getState());
    }
  }
}

import Reflux from 'reflux';

import Actions from '../actions/sa.Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';

function _GotData(data) { this.data1 = data; BasicStore.trigger('data1'); }

let BasicStoreObject = {
  init() { this.listenTo(AddonStore, this.onAddonTrigger); },
  data1: {},
  listenables: Actions,
  mixins: [MixinStoreObject],
  onGotData1: _GotData,
  onAddonTrigger() { BasicStore.trigger('data2'); },
  getData1() { return this.data1; },
  getData2() { return AddonStore.data2; },
  getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;
like image 147
J. Mark Stevens Avatar answered Nov 14 '22 21:11

J. Mark Stevens