I am using the container, component folder structure in my react app, where the container is used to connect the redux store to presentational components but as app grows larger there are many unwanted renders in components in spite of using pure components. Do we need to use container for react apps on using redux or can we use redux connect method on every component?
how to avoid unwanted rerenders on components and only re-render the props changed component is there any solution or pattern for this?
Related
I was trying to use redux in my react application but I see I can explicitly use redux in my application without using the react-redux library.
const redux = require('redux');
I am wondering then why do we even need react-redux library in our environment?
Can someone help me with this?
Redux is an UI-library-agnostic state management library.
React is a state-management-agnostic UI library.
React-Redux is glue between the two. You don't need it, but you'd have to implement the glue (hooks/HOCs) yourself.
In short:
React-redux is what makes your components rerender when Redux state that is being rendered by your component changes.
Of course you could also do store.getState().foo.bar in your component, but then you would have to track manually when that state changes and rerender your component. Otherwise, it would always stay the same and never update.
If you instead use useSelector(state => state.foo.bar), your component will always rerender when state.foo.bar changes, so you don't have to track that yourself.
react-redux contains in particular the Provider component and the useDispatch and useSelector hooks.
If you are using them, you're using react-redux. If you are not using them, you're missing out a lot, so I suggest you do.
When do we should use hooks over HOCs, and HOCs over hooks in React?
For example, I can perfectly have a hook for managing auth state, and then use it in a component... but I can also have a HOC which manages the auth state and wrap components for using its logic.
So... is there any rule to know if what interests you is to implement a HOC or a hook?
Why use HOC?
HOC is useful when you want to inject additional behaviors into the existing Component. You can use HOC to inject:
React Lifecycle (eg. execute code in componentWillMount)
State
(eg. react-redux’s connect) 3
Component (Parent Component, Child
Component, Sibling Component) Style
Why React Hook?
If you write a function component, and then you want to add some state to it, previously you do this by converting it to a class. But, now you can do it by using a Hook inside the existing function component.
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.
When I was learning react my instructor always remind me that I should use functional component as many as possible, try to avoid using class component, use class component sparingly. Yeah it was easy back then.
Now I am using Redux and I can barely using functional component because connect() imported from react-redux will only work with class component, as a result every component of my app are all class component. Is this normal? Since nowadays hooks API (which is using functional component) increasing in popularity.
Well, 2 things:
Firstly, it is possible to connect a functional component.
Secondly, you shouldn't be connecting every component to Redux. In reality the less components connected to Redux the better. Ideally, for a set of components, you have a 'container' component which is connected to the store (and which contains all the other relevant state and logic within it), then it passes that stuff down to the functional/class component children (which are more focused on presentation). Then you can have a few of these containers throughout the app, and the rest of the components are just traditional React ones.
If you connect everything directly to the store it can lead to problems like decreased reusability of components, poor performance or encouragement of bad component layout/hierarchy.
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.