Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to get action and state in store.subscribe? #580

Closed
antonmedv opened this issue Aug 19, 2015 · 6 comments
Closed

Is it possible to get action and state in store.subscribe? #580

antonmedv opened this issue Aug 19, 2015 · 6 comments
Labels

Comments

@antonmedv
Copy link

I want to update my view in listener:

store.subscribe(() => {
    updateView(store.getState()); // Some DOM api calls.
});

But if it possible to get last action what triggered state change, i can do some think like this:

store.subscribe(() => {
    switch (action.type) {
        case UPDATE_TITLE:
            updateTitle(store.getState().some.title); // Optimize rendering of view. Only one DOM api call.
        break;
        default:
            updateView(store.getState()); // Some DOM api calls.
    }
});

Is it possible to get action and state in store.subscribe?

@sergey-lapin
Copy link

I made some hacking around this https://github.com/lapanoid/redux-remote/blob/master/src/createSubscribeOnStateStore.js but I am sure it is not the best way to do this. Waiting forward for @gaearon comment.

@gaearon
Copy link
Contributor

gaearon commented Aug 20, 2015

This is not something we want to include by default. It's a hack around the paradigm, so if you really need it, please do so at your own risk.

Non-React Way

The easiest way is to have a reducer that remembers just the last action:

function lastAction(state = null, action) {
  return action;
}

Then you can use store.getState().lastAction, assuming you did something like

import { combineReducers, createStore } from 'redux';

const rootReducer = combineReducers({
  someReducer,
  someOtherReducer,
  lastAction // <-- use it!
});

const store = createStore(rootReducer);

store.subscribe(() => {
  console.log(store.getState().lastAction);
});

Still, this is not quite how Redux app is supposed to work, as this breaks the consistency in rendering.

React Way

If you want to optimize a React component, optimizations described in “Advanced Performance” is what you should be after; not this.

As a last resort you can always do side effects in componentWillReceiveProps:

componentWillReceiveProps(nextProps) {
  if (this.props.title !== nextProps.title) {
    // If somehow we're sure we can actually be faster than React at this. (not likely)
    findDOMNode(this).doSomethingWith(nextProps.title);
  }
}

@MujtabaKably
Copy link

@gaearon
thanks for this awesome idea.

i agree it isnt best way to do it in react, but when using react + other-libs to develop an app that using redux as data sync it is the best way to do it

@praburajan
Copy link

@gaearon @markerikson While this requirement is not needed for react and I do agree that its against the philosophy of writing code reacting to state changes rather than the event, it is important for other MVVM libraries to be able to use redux as the state management framework. Redux provides an awesome paradigm of writing all your business logic inside reducers which are pure functions, making testability, undo-redo very easy

@matigda
Copy link

matigda commented Oct 22, 2017

Can somebody please explain a little better the idea behind this?
Because IMO it would make a lot easier implementing some UI changes ( like lazy load reloading ) if the action is passed to the listener. Right now it is being fired on every state change ( that's ok ) but without any data provided you actually need to have some global variable to compare, as it is given in example above ( and that's not quite ok ). And without previous state or action being passed I can't really see the real usage of that method anyways. Judging from examples of that method usage it seems like there wasn't a clear idea how it can be used in real world application without violating any rule. So again... what exactly would be broken here if the action is passed to the listener?

@markerikson
Copy link
Contributor

@matigda : please see the linked issues for prior discussion, as well as the answer for this topic in the "Design Decisions" FAQ page.

@reduxjs reduxjs locked as resolved and limited conversation to collaborators Jan 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

7 participants