Whats the need of mapDispatchToProps in a react-redux application? - reactjs

Reading many articles and blogposts on this I understand(simplified)
mapDispatchToProps()(
clickHandler: ()=>dispatch(Action)
);
<Component onClick={this.props.clickHandler} />
Does the same as
<Component onClick={store.dispatch(action)} />
Which looks simpler than having all the hassle of using mapDispatchtoProps
I am new to redux and react in general and can't wrap my head around this. Is there an actual necessity to use it or is it just good coding practice?

There isn't an absolute necessity to use mapDisplayToProps but it will get pretty handy if your application grows.
In your second example you access the store object directly. This is not considered a good coding style because you couple your component to a global object which makes it harder to test the component in isolation or to use it in another context.
Think about each component as an isolated piece of software with the props passed to the component being the only interface to the rest of your application. This won't matter much for small example-like applications but pays off in real-world conditions.

The main idea of connect with mapDispatchToProps and mapStateToProps is to keep you UI components simple and easily reusable. Imagine, if you have 3 applications which have completely different architecture(redux, flux, pure React ContextAPI), but should reuse same UI components. If you incapsulate business logic directly to your components (2. example), then it might be very hard or even impossible to reuse it, because it is attached to some store (in the place where you use your <Component ... />).
Just as a side note and good example, how mapDispatchToProps can make your application clean is clear separation between business logic and UI component.
Example:
You have a Button component, which is used all over the application. Then you get a requirement that you need to have a logout button in different places of your application. One way would be to create a new regular React component, which will use the Button component inside and also have some logic.
connect with mapDispatchToProps comes to help you and allow to easily create a new LogoutButton component with attached logic (which also allows you to update the redux state), then whenever you need to have a logout button you simply use LogoutButton and there will be no need in any extra logic because it's all defined inside mapDispatchToProps and is already attached to the Button component.

mapDispatchToProps() is a utility which will help your component to fire an action event (dispatching action which may cause a change of application state)

Related

Redux/MobX - Do I need to pass data in child components via props in React?

I know It may sound like a dumb question, But I am not able to get this solved in my head. Please bear with me.
In case when we use a state management system in React like Redux / Mob X, I guess the main purpose of these state management techniques is to provide a single source of Data and a more structured approach of updating it.
Say, I am Using a state management library(MobX) for React, And suppose I have a parent component which makes an http API call and updates the MobX store with the API response. Now I need that data in one of child/nested components.
My Question is, Should I pass that data as a prop to child component or should I enable child component to connect with Central Store and directly get that data ?
by connecting the child to store, I am turning the Child into a class component, which is making it more heavy and React optimisations may not apply. I am defeating the whole purpose of a functional component.
Awaiting replies.
Best Regards,
Lalit
This completely depends on the situation. I would suggest splitting your components up in 2 parts:
Components that could be re-used in other projects
(Higher level) Components that are so specific to this project that they probably never will be re-used.
For components of category 1, I would suggest not using mobx store directly, but instead make pure react components. (eg think of a dropdown, or an ajax dropdown component).
For second part components (think of, header, footer, section components specific for your website). just make them directly interact with the Mobx store, so that you can way quicker code what you need (instead of constantly having to prop everything).
addition
For components of category 1 you can always wrap them with the #inject() method. This way for example you could turn a dropdown component into a UserDropdown component that uses the mobx store for its state. (The inject method injects mobx state as props in the component).
const UserDropDownComponent = mobx.inject(stores => ({users: stores.userStore.users}))(DropDownComponent);
// usage:
<UserDropDownComponent />
Warning
For pure components wont always see changes of mobx state. To Fix this you need to wrap the component in an #observe annotation. Or you have to inject the props by wrapping it into: mobx.toJS(yourMobxStateProperty)

correct react components interaction using redux

Let's suppose I have a Modal component that triggers an MODAL_CLOSE action when the user closes it.
Let's suppose I have an application that uses Modal component in many different places and, in some cases I want to change the application store when the MODAL_CLOSE event is triggered.
Is it correct to have, say a user reducer that listens for the MODAL_CLOSE action to make any change to the user portion of the store? Or by doing this I'm actually creating a coupling between the user "domain" and the Modal component?
What's the best practice in this case?
I'd say it's fine, because it's not coupling with the component, the connect call is doing the coupling.
Your reducer doesn't depend on the implementation of the component or even the existence of the component, just that there is an action MODAL_CLOSE(D?).
Likewise, your component is not coupled to or aware of the logic of the reducer.
I think it's correct. You would use something like <Modal onClose={closeModalAndDoSomethingAction} in the places where closing it has special behavior. The Modal component could then either dispatch its default onClose action, or the special one, if provided via prop. The special action would either be something other than MODAL_CLOSE or maybe have something in the payload that the reducer needs to make a distinction.

React state vs. Redux state (real usecase)

I have read multiple tutorials how to make CRUD in React with Redux bot none of the authors explained why they are using Redux. (Like they are only using it for fancyness or because all other are using it.)
Citate from here:
People often choose Redux before they need it.
Through further researching i learned that Redux is good for:
Share state between components
Let some data be accessable in the entire application
It does not exist a wrong or right. But only the do what makes sense.
My usecase
I have a component that uses a shared component:
¦-- domains/FooManagement/Components/Editor.jsx <-- Most-parent of the editor
¦-- domains/FooManagement/Components/..the children of Editor.jsx
¦-- shared/Components/Tabs/Tabs.jsx <-- Most-parent of the tabs
¦-- shared/Components/Tabs/..the children of Tabs.jsx
Tabs.jsx is used in Editor.jsx.
Which is the right approach?
Approach 1: React state (I think its the right one)
Every dynamic rendering that can happen is stored in the state of Editor.jsx.
onClick on a tab (nested shared component) calls a callback written in Editor.jsx that updates the state in Editor.jsx. This state change then rerenders the new active tab
That means that on every other component like Editor.jsx that uses the same nested Tabs.jsx, the changes for the tabs must be handled in the editor.
Code example:
/**
* domains/FooManagement/Components/Editor.jsx
* or
* domains/BarManagement/Components/Editor.jsx
*/
onTabChange(activeTab) {
this.state.activeTab = activeTab;
this.setState(this.state);
}
I think this is the right approach because:
I dont need the state of the editor or the tabs component in the entire application. But only on this view one time. Like the short term duration definition.
Approach 2: Redux state
Editor.jsx has its own state
Tabs.jsx has its own state
States are stored in Redux
Editor.jsx dont passes data down to Tabs.jsx because Tabs.jsx takes the data from the Redux store
Benefit:
The code example above must not be in Editor.jsx because its not the editor's interests how the tabs component behaves. (Or should the editor interests?)
I think this is bad because
Its too much magic in here. Immagine there comes more components in the editor like sortables, tables, etc. In the Editor.jsx you will not see what can render your view. It is hidden in the other components.
But if its all handled in Editor.jsx, you have the overview and the control of all what must be rendered on any change.
What is the right approach for you?
speaking of real usecases, I'm working on an everyday growing project, at first, pure React state management seemed like a very convenient way to develop, and it was working just fine when the components structures were still somehow flattened, but as we go along it, the project gets more complicated and by complicated I mean, more component become nested, and one parent has a serie of nested children, so we have to pass props all the way from the parent to the most furthest child, and whenever we need to rerender the parent, all the children have to go through this cycle also, as for your case, if you know that your project won't get way more complicated, and Tabs.jsx won't have maybe something like form that contains further nested subForm that contains a Grid maybe, you surely don't need to complicate your life with Redux, but as I stated earlier, for us we started to notice that at this stage, integrating Redux would be considerable

If given the choice, should I be passing data by passing through params or by connecting through the Redux store?

I'm using React and Redux and it's my first project in React overall. As of now I have a bunch of Components that all "get" and "set" the global data through Redux. So basically every component has this :
this.props.actions.UseInfo(this.props.commonData);
function mapStateToProps(state) {
return {
commonData: state.something.commonData
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(someActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ComponentName)
Now I noticed in React without Redux.. you have to structure your app to pass your data through parameters like
<SomeComponent someParam={this.commonData} />
<SomeComponent someParam={this.commonData} />
Is there any reason I should take the time to restructure my app to pass more information through parameters and use the Redux actions/reducers less unless if needed?
It seems like structuring to combine the best of both worlds .. maybe having the main components connect to the store and then pass that information down to it's sub components is probably the most ideal, but is there any reason why i "should" be doing that over just connecting everything through the store?
At the end of the day I feel like it's accomplishing the same thing.
Thanks for any input
Have a look at this article by Dan Abramov, the creator of Redux.
It says, basically, that container components get data via connect, and presentational components get data via props.
There are a couple of advantages to splitting out presentational or "dumb" components that simply react to their props. Namely, reusability and centralization (you know where to look for things, dumb components rarely require much maintenance).
In the real world it's never black and white, of course. Do the best you can but don't obsess over it, just do what makes sense for your app. Without knowing more about the hierarchy of your project, it's hard to know if you have a problem or maybe just a simple app and it doesn't make much difference. In general I would say watch out for nested "smart" components.

Where to write logic related to component that doesn't affect the UI directly

I have a component which contains a textarea. Whenever I enter text I run a set of validations against the text and depending upon results I update the UI. You can assume the code to be like this:
onTextChange(e) {
const results = this.runValidations(e.target.value)
}
Now, the problem is this.runValidations is like 100 lines of code sitting right there in the component but doesn't affect the UI directly and is specific only to the component and its child components. But, it makes my component file bloated.
So, is there any convention that other people follow in their React-Redux apps to handle such logical code that is specific to the component but is not part of the UI logic? Where do they place such code?
At the end of the day, most business logic doesn't have a lot to do with React/Redux - so they can usually be shovelled out into their own utility functions or classes. Which is great for a few reasons
a) easier to test because it hasn't zero linkage to React/Redux and
b) keeps your actions light, and
c) more encapsulated - having minimal knowledge of react/redux is not a bad thing.
It's all just Javascript - there is nothing wrong with importing custom business classes or utility functions.
Edit
My folder structure will typically look like:
my-component
child-components
Child1.js
_Child1.scss
Child2.js
_Child2.scss
helpers
util1.js // with a single default export
util2.js // with a single default export
_MyComponent.scss
MyComponent.js
MyComponent.spec
Where child components are (or should) only be pulled into this component. Ie. they shouldn't be used by other components.
This hashnode article also has a great structure if you are using redux as well: hashnode.com/post/tips-for-a-better-redux-architecture-lessons-for-enterprise-scale-civrlqhuy0keqc6539boivk2f
It seems that you are missing the concept of components vs containers (or dumb components vs smart components, as some like to name it). Basically, it is a good practice to apart your business logic from you pure presentational components.
Have a look at Presentational and Container Components, by Dan Abramov.

Resources