How action and reducers are connected with each other in react redux - reactjs

I am new to react and redux. I have gone through many online tutorials on react redux but still not able to understand how action and reducer is connected. If I am right, we import action in container/component, we import reducer in a file where we create a store. So there is a connection between container - action, and there is a connection between reducer and store but in action file we dont import reducer. So how action is connected to reducer. I know that we have a type of action which will be checked in switch case in reducer. But how does it get passed to reducer.

Very High Level Overview
Action - Actions can update state
{ type: ACTION_TYPE, somePayload: payload }
The redux store exposes out a dispatch function, that ultimately wraps an action creator.
mapDispatchToProps = dispatch => {
return {
someWrappedAction: () => dispatch(actionCreatorFn()),
someOtherWrappedAction: val => dispatch(otherActionCreatorFn(val)),
}
}
useDispatch Hook returns the dispatch and you wrap action yourself
const dispatch = useDispatch()
<button onClick={() => dispatch(someActionCreatorFn())}>
Do Action
</button>
Reducer
The reducers form a state tree, starting with the root reducer passed to the redux store. The "connection" is made (conventionally) via the mapDispatchToProps and connect HOC. (Now can get the dispatch from useDispatch hook)
Reducers are pure functions that take two arguments, current state and an action, and returns the next state.
(currentState, action) => nextState
So how is each dispatch in mapDispatchToProps connected to the appropriate reducer...
When you dispatch an action creator it passes the action object to the root reducer. The action object is passed through the entire state tree and any reducers that process the action type consume it.

TLDR: dispatch function takes action as an argument and calls currentReducer(..., action).
When you call creteStore(reducer), the returned object contains dispatch and subscribe functions.
When you (or react-redux library) call subscribe(listener), redux will remember your listener function (in case of React, the listener has to make sure the component re-renders with new props, context, state, or refs - depending on concrete implementation).
When dispatching an action with dispatch(action), the dispatch function will call reducer(action, state), modify redux internal currentState then call each listener().

Related

what happens after dispatch function and reducer function in react-redux?

suppose if i dispatch an action using dispatch() , i know that reducer() is called which has an action object and current state as parameters . i want to know what calls that reducer function ? which functions are called before reducer function and after dispatch function ? after reducer function returns the new state ,which functions are called after that ? where does this new state goes ? does usestate() and useselector() also returns something after reducer function returns new state ?
i want to know what calls that reducer function ?
which functions are called before reducer function and after dispatch function
dispatch() indeed 'call' every reducers. It uses an event system and all reducers are listening to this event (this is all behind the scene).
Still, you can write a piece of code that will be inserted between the dispatch call and the reducers catching actions.
It's called a middleware.
A middleware can intercept any action triggered by a dispatch, also it has access to the store.
At the end of your middleware your just use a callback to tell the flow to continue.
You need to pass your action to it so your reducers can finally be called and receive the action.
Here is an example of middleware that log any actions that are sent by any dispatch()
const logger = store => next => action => {
console.log('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
return result
}
To make it work you need to pass your middleware to your redux configuration, so they can be called.
after reducer function returns the new state ,which functions are
called after that, where does this new state goes ?
If you look at your redux configuration you'll see somewhere that you combine all of your reducers ( often called root reducer).
const combinedReducers = combineReducers({ reducerA, reducerB })
const store = createStore(combinedReducers )
Redux use this combination of reducers to fill the store, so anytime a reducer return it's result, it can be save in 'the store'
does usestate() and useselector() also returns something after reducer function returns new state ?
useSelector() is a hooks that has the ability to read in the store. (Store that contains the fresh result of your reducers and is updated every time there is a modification in the store)
useState() is not related to redux. It's related to React. With useState you can read and write in the local state of a component.
It returns you a piece a your state and a setter for this piece of state.
const {myPieceOfState, setMyPieceOfState} = useState({ something :'a default value for myPieceOfState'})

Unable to understand how redux dispatch is accessible

I'm trying to learn redux and the tutorial I'm following along has the following syntax in the userActions file
export const loginUser = (userData) => (dispatch) => {
dispatch({type: 'something'})
}
However when we call the loginUser function (in another file) the syntax is like this
this.props.loginUser(userData)
I was wondering where does the dispatch come from? Why don't we get dispatch is undefined for calling it in this manner
The dispatch function is made available because you're using redux-thunk, which is a redux middleware. And because of this middleware, your action is able to fire multiple dispatch to your reducer.
dispatch function comes from connect function of react-redux. Connect function receives mapStateToProps and mapDispatchToProps.
With mapStateToProps, redux map state from reducer to this.props of your component
With mapDispatchToProps, redux will call a function like login, after login redux will dispatch an action with some new states(optional) to let you know login success or failed. Those states will be passed into your component through mapStateToProps
Redux is a state container which is used to have a global state which can be access from all over the project. so we have to inform the global container about our state changes such as create,delete and updates. To inform the changes we use dispatch and we provide a referring name called type. in some cases we pass the data also to dispatch with the referring name of payload.
the first function you wrote was trying to login with the user data. the function is needed to be called in login component. so we pass the function as prop to the login component. now the login function is in your props so simply call is as
this.props.loginuser(userdetails)

Dispatching new action after global state changes in react redux

Lets say i have a form where user is about to click on combination of buttons.
Each button triggers an action of type T and reducer R then updates its state and new combination is rendered on a website.
Now comes the tricky part:
I have my business logic implemented in reducer which applies new state which is about to be rendered. What i need now is when that state accepts a condition, i want to dispatch new action (api request).
What is the right approach to accomplish this kind of problem?
Set a flag into state, and call new action in component after?
Somehow dispatch a function in reducer?
...?
Redux Thunk allows you to dispatch multiple actions and dispatch asynchronous actions inside your action creators. For your scenario, you can do something like this:
function myAction() {
return (dispatch, getState) => {
...
dispatch(firstAction);
const state = getState();
// Check your state conditions from first action here.
dispatch(secondAction);
...
}
}
In this case you could use library redux-saga.
Using redux-saga, you'll be able to create a saga that you call from a component like actions. In the saga you will be able to call several redux-actions. If your state will be valid from the saga, you can call the API request.
A popular alternative to redux-saga is also redux-thunk.

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)

Resources