Best practice when passing Redux state into components - javascript

I'm working on a React + Redux project with a couple of other developers and we can't agree on what the best practice is regarding where to pass in the state and the actions.
My approach is to have a 'container' or 'provider' component, which is the parent component, all required states and actions are mapped to state and passed down into child components, creating a single source of truth. However the down side to that is, you have to remember to pass actions and values down through each child component, which can be tricky to follow.
Another developers approach is to use the mapStateToProps on each component where it is needed, at any point in the stack. So if a child component three or four levels down requires a certain state, he would use mapStateToProps on that component. He would also import action creators directly using the import keyword, instead of calling them as props. I don't like this approach because you're potentially injecting states multiple times and you can't switch out your state or actions quickly in one place.
I can see both approaches have their merits and fallbacks, so I just wondered if there was a definite best practice as to where and when to inject state/actions into a stack of React components.

I worked on a relatively large Redux codebase and the approach we chose and which I like was your second approach using mapStateToProps on containers component which dispatch actions and delegate rendering to dumb components.
You want to be able to reuse them in many places without having to pass down a state. Your top redux state is still the source of truth but mapStateToProps will allow you to access only the part of the state which you need within this container.
Redux documentation is amazingly well done, check it out, it recommends container components implementing mapStateToProps http://redux.js.org/docs/basics/UsageWithReact.html

It's up to you how many components you connect to Redux, but generally speaking having more connected components is better for performance. For more information, see the Redux FAQ on connecting multiple components, as well as my blog post Practical Redux, Part 6: Connected Lists, Forms, and Performance.

Related

React-Redux: Do I have to use connect() and map state/dispatch on all my components from a single component tree? Is there a way to do it only once?

So basically I have an app with a single component tree. App as a parent and then it goes down from there. Initially, all of the states are obviously centralized from the parent component App, as it is normally, and then the state is passed per component via props. We all know this is a hassle as the component tree gets bigger and bigger.
I'm studying React-Redux and just curious if I always have to use connect() and then each create a mapStateToProps and mapDispatchToProps for each and all my components including the subcomponents? Is there a one-off way to do this? Isn't it possible for my many components to just access the entire store without mapping each state/dispatch to props one-by-one, which I find repetitive and time-consuming?
I came from a Vue-Vuex background (although my Vuex experience is limited) and React-Redux is just a whole different ball wax, if not quite a lot more complicated IMO.
Per the Redux FAQ entry on "Should I connect all my components, or just one?":
Early Redux documentation advised that you should only have a few connected components near the top of your component tree. However, time and experience has shown that such a component architecture generally requires a few components to know too much about the data requirements of all their descendants, and forces them to pass down a confusing number of props.
Emphasizing “one container component at the top” in Redux examples was a mistake. Don't take this as a maxim. Try to keep your presentation components separate. Create container components by connecting them when it's convenient. Whenever you feel like you're duplicating code in parent components to provide data for same kinds of children, time to extract a container. Generally as soon as you feel a parent knows too much about “personal” data or actions of its children, time to extract a container.
In fact, benchmarks have shown that more connected components generally leads to better performance than fewer connected components.
In general, try to find a balance between understandable data flow and areas of responsibility with your components.
With Redux you don't have to connect all the components to its store. You only connect the components that really need it. For example, if a connected component has children then it might be simpler not to connect the childeren to Redux but rather let the connected parent drive the updates for its children. Grandkids can be coonected but not their immediate children and so forth. There can be many approaches and every component can still have its own private state in addition to Redux store.
Currently React.FunctionComponents are in fashion and you can use useReducer hook instead of connect though you will have less possibilities to fine-tune for performance with the hook.
Your state in redux store doesn't change, but in order to use it, you should use connect and connect to your store.
If you don't want to use connect,
you can simply pass your states to a child component by props like
<mycomponent data={this.state.data} />
And use your data in your child component
If these ways not satisfying you can read about the context system, but it's parent to the child again, but you can pass data from parent to grandchild without using child
You can read about it here
Hope this helps you.

Connecting child components to store vs connecting parent component to store and passing down props

After a lot of search and working with React and React Native. I still have a pretty vague opinion on which
is best to use and in what situations
Having the parent component be connected to the store and passing as props all data to children functional components. This what I initial though was the "React" way but pretty soon I saw that as the app grow the amount of logic handled by this parent component starting too be to big and messy.Also child components start to have children of its own and so on and so forth.
Having parent component (Screen for example) that is functional and each child that needs information from the store will be connected to it. This is much more "clean" solution but will create a lot of store connection "duplications" which are not necessary.
Using Redux store
My question in general which is more recommended pattern to use and in which use cases, also would be nice to know what is the price for having a lot of connected (containers) components
Not sure i can provide a right or wrong answer for this question as each has its pros and cons.
My rule of thumb is to connect deeply nested components only when their parents are "proxies of props". That is they accepts props only to pass them down to their children.
If i may quote (myself) from this answer:
Avoid connecting components when you can and pass down the props to
the children, the main reason for this is to prevent dependency on
redux. I prefer keep my components "dumb" as i can and let them
concern only on how things should look. I do have some components that
concern on how things should work and these components are mainly
dealing with logic and passing down data to the children, they are the
components i often connect.
When i notice that my app is scaling and some of my components are
acting as a proxy of props (i even got a word for that! "Propxy"),
that is they get props from their parent and pass them down without
using them, i usually inject a connected component in the middle of
the components tree so i can let the "propxy" components down the tree
flow be more lighten and slim
You should also note that one more pitfall with connected components is that each render will trigger the mapstateToProps method. if you got some heavy logic there you should memoize it, usually done with reselect
As for the benefit of connecting a component, well you probably realize that already. you get quick access to the Provider's state via react's context.
Edit
As a followup to your comment:
about the rendering - wont I have much more unnecessary rendering if Ill have a deep nested children (common in medium to large apps) that will be unnecessarily re rendered on each parent update
Well the connect HOC wrapper won't trigger a re-render if the previous object of mapStateToProps is the same as the current object returned. so no unnecessary re-renders to your connected component will take place.
You can read in more details on how it works and how the logic was evolved over time in this article
I use the first option.
The cons you wrote are correct, but i think its easier to debug and understand the data flow this way.
Don't connect a component to redux if the current component doesn't use this data from redux and only passes.
If the component uses data then connect to redux.
If the current component uses data from redux and the next component also uses it then you can pass and don't need to connect the next component to redux.
MAIN RULE:
if there is a gap in the data usage chain from parent to child then don't need to pass data from parent to child
connect(parent) (don't use props) => child (don't use) => child (don't use) => child (using) - better to connect last child. Isuue related to props dreeling

How & when to best modularise Components with & without Redux?

Say I want to create a little editor for my software that helps me organise people in my company. I will use React & Redux. The editor is a React component (or maybe container?), and it shows me one person at a time. I can edit things about this person, delete fields, etc. and when I am ready I can click a button which will then give me the next person to edit.
Now, I am quite new to React still and can imagine doing this in 2 ways:
Solution 1: Decouple the editor component
Create an Editor Component, which takes an array of all the people in my company. I do have these people saved in the Redux state of my app, but the editor component will not work on my Redux state, but do all changes in its internal state first, and only once I click save will the Editor component commit these changes to my Redux state. This might be a problem, and changes could get lost if somebody doesn't save their edits.
The advantage here is that I have my Editor de-coupled from the rest of my App, and the logic of the Editor will stay in that component.
Solution 2: Connect the Editor Component to Redux
Here, I would connect my Editor component to Redux. So I would not give my component the people array, but direct access to the my Redux store via selectors (for example). I would also not have a deletePerson() function internal to my component, but pass this down as a prop into my component (and it would presumably be a Redux action). This way my component would work directly on state, which I can see as having advantages.
But taking it out of this app and reusing it somewhere else would get more and more difficult, the more complex my component becomes.
Please remember that I am a beginner and that these two solutions are what I came up with as a response to a problem I am facing in my own application. However, I would appreciate if you could help me out here, and explain to me how I should think about problems like this. Is there maybe a third solution I am not mentioning? Or am I misunderstanding a concept?
Personally, I am inclined to go with Solution No. 1, but I also know that the whole idea of Redux is to keep state in one place. What would you advise? Are there performance differences / advantages with one solution?
Your first solution is good but why not use a service when its provided?
You should try to mix up features of Redux React. First, separate your presentational and container components and in one of your container component pass the props directly to redux store on click,etc. Then use redux actions to access the store like deleting,etc. Provide a UI using React presentational components for data entry and pass this data to redux store. Use redux actions when you think they will be useful and not destructure your app.
Go to https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 for further details on how to connect presentational and container components.

why do I need redux in react native?

I am trying to find out why do I need redux if RN already have state, I can use state as I want as action or change something.
So why would I need it?
Redux provides a "shared state" that every component can access. For example, you may have found that a parent component needs to be aware of the state of a child component. You can resolve this in React alone by passing down a method as props to the child but this isn't a pattern you want to be repeating again and again, especially as your component structure becomes more complex and hierarchical. Redux provides an elegant solution. For small apps though, it's probably not necessary.

Should a container component *always* connect to Redux?

I'm about to start a new React project and am trying to draw on my previous learnings to create some rules about how I structure the app.
Some things I believe to be true:
Redux holds the 'main' data for the whole application
Redux can hold UI state if it needs to be shared across the application (e.g. global modal windows that can be launched from anywhere)
Components can hold their own state with setState if that state doesn't need to be shared anywhere else in the app.
Stateless components should be used wherever possible
When I am creating a component that needs state from Redux, I will create FooContainer.js and FooComponent.js files - the Redux connect code will sit in the container.
There are large parts of the app that are UI heavy and have a lot of UI logic/state going on, but do not need any state from Redux.
I feel that with the liberal use of component-level state, I should be using more Container Components to compose smaller, stateless components. However, I see a lot of definitions of Container Components as "a HOC that connects to Redux"
Does it make sense to have a project that has many container components, where some are Redux connected and pass data from the store to their corresponding presentational component, and others that are not Redux connected but are just used to compose smaller components and manage local state?
If so, are there any recommended file structures, naming conventions etc to distinguish between the two?
A few thoughts.
First, it's important to understand that a "container component" is simply any component whose primary job is to fetch data from somewhere and pass that data to its children. This could mean making AJAX calls to retrieve data, or accessing Flux stores. That means that the wrapper components generated by React-Redux's connect function are "container components", because their only job is to extract data from the Redux store. It also means that components whose job is to manage UI state are also "container components". See Dan Abramov's original article on container and presentational components.
Second, it's entirely fun to use class components and functional components, as much or as little as you want. That's purely up to you.
Third, while you can define your "plain" components in one file, and "connect" them in another file, I personally tend to see that as unnecessary separation. Most of the time, a given React component will only be connected once, so it's perfectly reasonable to define the component and connect it in the same file.
You may want to read through some of the articles on Redux Architecture and Project Structure in my React/Redux links list for more information.
Revising your assumptions:
Redux holds the 'entire data for the whole application in a store.
Redux can hold UI state if it needs to be shared across the application in the store.
Components do not hold their own state they reference the main store (even indirectly using connect)
Stateless components should be used wherever possible. State is passed by the container.
When creating a component that needs state from Redux, I will create FooContainer.js and FooComponent.js files - the Redux connect code will sit in the container.
Answering your questions:
Does it make sense to have a project that has many container
components, where some are Redux connected and pass data from the
store to their corresponding presentational component
Yes - Dividing your app in smaller components with their own containers is good practice.
and others that are not Redux connected but are just used to compose
smaller components and manage local state?
Not really IMO - In Redux the state of your app should be kept only in a unique store. Still you can have smaller simple components in a container if related.

Categories