Getting Redux State in action creators without Redux-Thunk middleware - reactjs

Hi I am building a React/Redux app and wanted to get state values inside action creators. I can get state using Redux-Thunk middle ware like this
export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
return (dispatch, getState) => {
const {items} = getState().otherReducer;
dispatch(anotherAction(items));
}
}
I found some code on stackoverflow to import store in action creators, but somehow I need to know how to import store in action creators.
Is there a way to get state in action creators without using middle ware?

Related

React-Redux example has a non-pure function. I thought reducers had to be pure?

Redux says that actions handling the state (Reducers) have to be pure.
Looking at the React-Redux docs, though, they show how to add a new Todo task to the list of Todos and the function generates a new identifier for the new Todo task. This is obviously not pure. Calling the same function again will not result in the same output.
There is the example (from this page):
// redux/actions.js
import { ADD_TODO } from "./actionTypes";
let nextTodoId = 0;
export const addTodo = content => ({
type: ADD_TODO,
payload: {
id: ++nextTodoId,
content
}
});
// ... other actions
Does that means I have to forget everything I learned so far?
It looks to me like that's an action creator, not a reducer. Action creators don't have to be pure.
Action creators can also be asynchronous and have side-effects.
https://redux.js.org/basics/actions#action-creators

Dispatch in react redux

I am new to react and redux xo my questions will sound basic.
What does dispatch means? I am referring to the term dispatching an action.
Why do we need mapDispatchToProps to store actions on redux? We can simply import an action and use it. I have a scenario in which I have to load data when a component is mounted.
#mariazahid mapDispatchToProps will bind the action to your component so that you can pass it down to your presentation components. This is a pattern that is normally used within using Redux with React.
You can import your action and just dispatch the action, but in most scenarios a container -> component pattern is used. A container is where the actions are mapped to and the state and the only goal of this component is to pass this data down to components that are used for presenting that data.
When working in teams, it's a pattern that is easily adoptable. Instead of importing actions from left right and center, you will just have to be aware of the container and how it passes the required actions/data down to the children.
From an implementation perspective, dispatch is just a method that is used to communicate with your reducers
Let say that your action looks something like this
function myAction() {
return { type: 'MY_ACTION' };
}
You're trying to communicate with the reducer that responds to the action type 'MY_ACTION'
In your mapDispatchToProps you'd typically do something like this;
function mapDispatchToProps(dispatch) {
return { actions: bindActionCreators(myActions, dispatch) }
}
Effectively, you're wrapping(binding) your actions to the dispatch method;
function bindActionCreators(actions, dispatch) {
// this is a very trivial implementation of what bindActionCreators does
let wrappedActions = {};
Object.keys(actions).forEach(action =>
// for every action, return a function that calls dispatch on the result of what your action returns
return function(...args) {
// remember here that dispatch is the only way you can communicate with the reducers and you're action's type will determine which reducer responds to return the new state
return dispatch(actions[action](..args));
}
);
}
And so, these "bound" actions are now assigned to a props.actions in your component.

Best practices for redux action creators

What is the best practice around redux action creator when it comes to calling action creators for 2 different events for a same functionality? Using redux-thunk to dispatch the actions.
E.g. Lets say I have to write an action creator for saving and printing the user name. Which action creator is better between the 2 below and why?
Action Creator 1
export function actionCreator1(actionType)
{
switch(actionType)
{
case "save":
// dispatch
case "print":
// dispach
default:
}
}
Action Creator 2
export function actionCreatorSave()
{
// dispatch
}
export function actionCreatorPrint()
{
// dispatch
}
Both are wrong. In redux, action creators don't dispatch actions. They return actions that you dispatch (in React this is preferably within react-redux mapDispatchToProps function).
http://redux.js.org/docs/basics/Actions.html#action-creators
mentions this as opposite to flux.
(the exception being async actions)

redux pre-binding through bindActionCreators, an anti-pattern?

Throughout my redux App, I frequently finding myself using the following pattern
// declare an action creator in a centralized / state management related location in the App (i.e. not the components/containers)
const myActionCreator1 = () => (dispatch) => { ... }
const myActionCreator2 = createAction(ACTION_2)
// then later in a mapDispatchToProps of a Container component
function mapDispatchToProps(dispatch) {
bindActionCreators({myActionCreator1, myActionCreator2}, dispatch);
}
Is these cases, is it an anti-pattern to pre-bind the action creators? given that there is only 1 dispatcher in redux working against 1 store?
i.e.
// actionCreators.ts
export const myActionCreators = {
myActionCreator: bindActionCreators(..., dispatch)
}
If this is pattern has no downside that would be good news for conciseness ....
Clarification
the conciseness benefit will only be apparent when multiple components re-use the same action creator. As these components will no longer require a mapDispatchToProps for straight-forward cases like the examples above
The connect function supports an "object shorthand" syntax for the second argument. Instead of creating a mapDispatchToProps function that receives dispatch (and probably uses bindActionCreators inside), you can just pass an object full of action creators directly to connect:
const actionCreators = {
addTodo,
toggleTodo
};
export default connect(null, actionCreators)(MyComponent);
That object full of action creators will be automatically run through bindActionCreators, and calling this.props.addTodo("Buy Milk") will dispatch the action creator appropriately.
I discussed some of the advantages of this approach in my blog post Idiomatic Redux: Why use action creators?.

In React with Redux, when should I save data to back end

In React with Redux, when there are some user operations, e.g., in facebook, user adds some comments, I will call dispatch() to send the add action to redux store, but when should I call back end API to save these data to database? do I need to do it together with dispatch()?
thanks
One solution would be to transfer your API logic into a thunk using a middleware package such redux-thunk (or similar).
Using thunks allows you to treat special kinds of actions as functions which means you can extend a plain action with specific action-related logic. The example you give of needing to serialize your state is an excellent use-case for redux-thunk.
You should note that, unlike reducers, thunks explicitly support fetching state and dispatching subsequent actions via the getState and dispatch functions.
Below is an ES6 example of how such a multi-purpose thunk might look.
To demo the getState() method the new item will only be saved via the api only if the redux state shouldSave value is truthy.
I would also use the async/await syntax to make sure the the api call succeeds before dispatching the local redux action.
Thunk Example - adding a new item
import api from './api'
export const addNew = async (item) => {
return (dispatch, getState) => {
try{
const state = getState()
if(state.shouldSave){
await api.save(item)
}
dispatch({
type: ITEM_ADD_NEW,
data: item
})
}catch(err){
const error = new Error("There was a problem adding the new item")
error.inner=err
throw(error)
}
}
}

Resources