Accessing Redux State in an Action Creator

How to access redux store from action creator?

You'll need thunk in order to enhance your action creators. the reason why you're getting the "must be plain objects" error is because your action creator is returning a function(), not an object. Thunk allows you to return functions in your action creators and with it, the code you wrote should work.

import { createStore, combineReducers, applyMiddleware } from "redux"
import thunk from "redux-thunk"

const store = createStore(combineReducers({
data1: reducer1,
data2: reducer2
}), {}, applyMiddleware(thunk))

Hope that works.

Accessing state in a Redux action

You can get the state in your actions too.

For example in this action you can do this:

export function isAuthz(allowed, except) {
return (dispatch, getState) => {
const state = getState()
// do stuff
}
}

Redux accessing state from action

Your action creators should generally be pure functions that don't result in side effects. The reason you don't want to access state in your action creator is because that means the result of setCategory() cannot be predicted based on its arguments. The whole point of Redux is to be able to reason about the state of your application in a straightforward way. If you can't easily follow the change in state that resulted from a given action being dispatched, that becomes much harder.

When you need to conditionally dispatch an action based on whether some part of state exists or not, then it's clearer to do that in "client" code (i.e. the client from Redux's perspective), which in this case would probably be a component. You can do the check and then dispatch some kind of LOAD_DATA action if the data is missing.

However, if you need to do something asynchronous, then you should investigate common patterns for async operations in Redux, or use an existing library, like Redux Thunk or redux-saga.

Best Way to Get State from Redux Store in Action Creator

I recommend that you take a look at reduce-reducers.

The well-known combineReducers() that Redux provides runs reducers in parallel, if you will, with each reducer only being aware of the piece of state within its own scope. Other configurations of reducers are possible. For example, you could reduce an array of reducers, running each in series, meaning that each will get a freshly computed state object from its precursors to use to compute the new state that it will pass on.

In your case, this would allow your reducer to know about selectedNode while reducing your ADD_CHILD action. If the parentId is not set in the action, the reducer can default to selectedNode. You just have to make sure that the reducer that changes selectedNode runs upstream of the one handling ADD_CHILD.

This covered in a nice way (with examples) in the Redux docs Redux docs: sharing-data-between-slice-reducers.

Using this pattern will allow you to avoid thunks, maintain simple action creators, still have simple component selectors, keep your state logic in the reducers where it belongs, and still keep your reducers pure. Having tried most of those other patterns you mentioned myself, I recommend this approach.

Good luck!

Redux pattern for getting state in action creator

I always follow the latter example, meaning that my action creators are not dependent on a store. However, there was a case when I had to pass user token to almost every action that required interaction with server API. Instead of repeatedly pass it to every action creator or accessing it within with getState() I wrote a custom middleware (not that difficult) that would recognize these actions and enrich them with another prop called userToken.

Back to the Dan Abramov answer. He says in a comment:

It’s fine to read from the store in the action creator.

which is confusing to me, but I think what he meant is that is fine to do it for certain reasons:

I think it’s acceptable is for checking cached data before you make a
request, or for checking whether you are authenticated (in other
words, doing a conditional dispatch)

... and that using getState may result in a situation where:

... it is hard to trace where those incorrect values come from
because they are already part of the action, rather than directly
computed by a reducer in response to an action.

What I think he means is that action creators should not pass updated parts of the store that get replaced by the reducer, but action should describe what is happening and the reducers should handle the update:

Not:

here is the new item list - replace it in the store

But:

we need to remove the item with id: 5 - handle it

...which is a bit different scenario than accessing a value from store to use it in a request. I advice you to read the linked blog. It answers in deep your question and there are some arguments with examples about whats best. TL;DR - it's a debate which approach is better.



Related Topics



Leave a reply



Submit