Access dispatchedProps actions in mapStateToProps - reactjs

I need to call an action in mapStateToProps, how can I have it?
const mapDispatchToProps = {
someAction,
};
const mapStateToProps = (state, props) => ({
globalParameters: 'some code goes here ...',
relatedDropDownValue: someAction({SOME_TYPE}),
});
The real code is more complicated but I simplified it.
I need to call someAction but I don't know how to get it in mapStateToProps. Is it possible at all?

mapStateToProps is not the place to dispatch actions, rather just to map some state from redux store to the props in your component.
The logic should be refactored as such that the component can decide on what action to dispatch (i.e. useEffect).
So the component must have enough data from the store, to decide what parameters should be given to the action to dispatch.
If there is a need to fetch data, the component should decide to do that, just keep in mind that whatever you wanted to do in the mapStateToProps, should be moved into the component and be dealt with.

Related

Defining mapDispatchToProps As An Object

I am just wondering for Defining mapDispatchToProps As An Object how can I pass ownProps to it? like in the function I can pass props as an argument.
const mapDispatchToProps = (dispatch, ownProps) => {
toggleTodo: () => dispatch(toggleTodo(ownProps.todoId));
};
for an object how to pass ownProps?
const mapDispatchToProps = {
toggleTodo
};
My account got blocked by some down votes questions, the funny thing is I have to re-edit them, even though I already have the accepted answer.I do not understand what's the point to do this.I am so frustrated by this stackoverflow system.
Now, I basically can do nothing but keep editing my questions, and they have all been answered. This is ridiculous !!!
Short answer: You dont need to. You pass the props into each action as they are called and needed.
Long answer:
mapDispatchToProps connects your actions to dispatch in the component so you can call the action and pass in required props for it using this.props.action instead of awkwardly finding dispatch and using this.props.dispatch(action()) or similar.
I find it's simpler to connect your actions to your export and call the action this.props.addUser(prop1,prop2) when needed - onClick(), componentDidMount() etc. It by default assigns dispatch to it without needing to do mapDispatchToProps. So
export default connect(
mapStateToProps,
{action1, action2, addUser})(User)
then you can use:
addNewUser = () => {
this.props.addUser(this.state.person);
}
where you pass in the props you're after and then do any other work the action or reducer itself (depending on your preference of flow) such as:
export const addUser = user => ({
type: ADD_USER_SUCCESS,
payload: {user}
})
ownProps can't be passed to it without doing the wiring in mergeProps function passed in the connect function.
You see, when mapDispatchToProps is an object, whenMapDispatchToPropsIsObject is invoked. It in turn invokes wrapMapToPropsConstant which does this
constantSelector.dependsOnOwnProps = false
Now, this property is used to decide whether the action dispatcher should be invoked with props or not. See all handle* functions like handleNewPropsAndNewState in src/connect/selectorFactory.js
This is in contrast with what happens when mapDispatchToProps is a function. In this case, wrapMapToPropsFunc when invoked wraps the action dispatcher and then invokes it with props.
Without passing mergeProps, you'll need to forward id prop to the action creator in the Component that is connected with the mapDispatchToProp
e.g.
onClickToggleButton = () => {
const {id, toggleTodo} = this.props
toggleTodo(id)
}

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.

Selector being called even when I don't mutate what its mapPropsToState

I have a React app that does some simple recording. I have a Component Recorder which connects to my redux store like this:
export default connect(
state => ({
recordings: state.recordings,
recordingSelector: selectRecordingBufferWithID(this.recordingID)
}),
dispatch =>
bindActionCreators({
startNewRecordingAction,
stopNewRecordingAction
},
dispatch
)
)(SampleRecorder);
The problem I'm having is that selectRecordingBufferWithID in my redux code is firing too often. Part of my reducer code looks like this:
function samplesReducer(state = [], action) {
switch (action.type) {
case MORE_SAMPLES:
return [...action.samples];
default:
return state
}
}
function recordingsReducer(state = [], action) {
switch (action.type) {
case NEW_RECORDING:
return newRecording(state, action.recordingID);
case STOP_RECORDING:
return stopRecording(state, action.recordingID);
default:
return state
}
}
const rootReducer = combineReducers({
samplesReducer,
recordingsReducer
})
const store = createStore(rootReducer);
export { store };
So, while I want selectRecordingBufferWithID to be utilized only when a START/STOP_RECORDING action occurs, it is called for each time MORE_SAMPLES is called.
My understanding of react-redux is that the selector is part of the mapStateToProps function that the connect function accepts. And somehow, connect cause my component to render and for its props to be updated with the mapped state from the redux store. the selectRecordingBufferWithID selector will also be called each time this happens so I can do a refined getter into the store.
So to summarize, my recordingSelector is firing more often than I expect. My only theory is that my reducers are somehow mutating the state of state.recordings each time it tries to reduce state.samples which makes react-redux render my component with it mapped to state.recording.
But otherwise, I'm stuck.
connect does not work the way you think it does. What it really does is:
Subscribe to the store. This subscription will be triggered after every dispatched action.
Execute your mapStateToProps to inject the initial set of props to your Sample Recorder component.
When any action dispatches, the subscription kicks in, and connect applies again your mapStateToProps to new global state.
If your selector returns the same props as before, it won't render your SampleRecorder again.
So the misunderstanding is that your selector shouldn't be called. But the fact is that connect needs to call your selector to decide when to re-render and when not.
The summary of this is that your selector should be either simple, or memoizable using reselect to avoid expensive calculations. You didn't show you selector code so we can't tell from here. :)

when is mapDispatchToProps function used

I have come across this piece of code while learning react-redux
export const mapDispatchToProps = (dispatch, getState) => {
return ActionCreators({completeDriver}, dispatch, getState);
};
I want to know when to use this function.
as per redux actions are dispatched like dispatch(actionCreator())
for doing so inside an react component you need the reference of dispatch which need to be passed as prop to your component.
so if you use connect() you can reduce this passing of dispatch as prop by yourself this thing will be handed via connect HOC(Higher Order Component).
for larger scale application using mapDispatchToProps of connect would saves lot of dev time of wiring things.

Would the following mapStateToProps function create performance problems with redux connect()?

I would like to pass all the redux state into an easy to manage key on my props (I'm doing the same with the action creators). I would de-structure the state off the props that I actually need in the components that would consume them. Would the following create performance problems?
const mapStateToProps = (state, ownProps) => ({ reduxState: {...state}})
Inside my component I would destructure the state to consume like:
const {
geosuggestLocation,
mapLocationDetails,
userWants,
smartySuggestion,
geocodeAddress
} = this.props.reduxState
So far, everything works as expected, I would just like to know if it's a pattern I can continue to use without performance issues later down the road.

Resources