-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
container vs component? #756
Comments
As for me, For example, containers/properties.jsx
and, for example, components/properties/pagination.jsx
|
Reading from the links you provided:
I get more the feeling that "containers" are actually what in redux is called "smart components"... and routes/pages should get their own folder. I'm not sure why "container" and "route handlers" are in any way related? |
It's a very common practice to group your app's components by route. As @theaqua pointed out, it's also common to make each route handler/component a smart/container component. If you're using combineReducers, you'll often find yourself breaking up state, routes, and containers along the same lines. Hence, they often get associated together. |
@ronag I didn't think you need make containers and pages. Why you can't put route handler & redux connector to state in 1 place? It's very handy. Keep it simple. |
In my application I only have 3 routes/pages. On the other hand I have lots of independent panels/modules. Making one huge If I do all the mapping from state to props and all data fetching in a single file it would be unmaintainable. Especially if I do all the data fetching at the same location. |
If you have 3 routes, so you need 3 route handlers. For example, In each container you pull part (not entire!) of redux state and actions binds. Then you pass down this to components like in my example. It's very maintainable, because I (and my team) know — connect to redux and actions binds always in |
I think I understand your suggestion. However, as I said those 3 files will become very complicated if I put all my data fetching there. In our cause it would basically be "Login, App, Logout" where App would contain almost everything. |
Maybe I'm too biased to I'll try your suggestion and see where we end up. |
I call I call |
@gaearon: Perfect. That clarifies the examples. Thank you. |
@gaearon So "dumb components" are stateless components, which can be written in a simpler syntax Since React 0.14, for example: var Aquarium = (props) => {
var fish = getFish(props.species);
return <Tank>{fish}</Tank>;
}; Am I correct? |
@soulmachine yep. |
Not necessarily. Syntax is not the point. "Dumb" components aka "presentational" components are components that receive all data by props, aren't aware of Redux, and only specify the appearance but not the behaviour. |
Although the term "container" is already quite popular in the react/redux nomenclature, we decided to call them "connectors" in the project I'm working on, to avoid any confusion with layout/graphical containers. |
btw, how to call them was previously discussed here reduxjs/react-redux#170. I keep everything inside a |
@gaearon so is a component that |
Yeah it can be occasionally useful although I prefer to |
What about when you're building a module of components? For example, suppose i have a separate node module for our navigation menu
so do I just name it 'NavMenuContainer'? that seems weird to me. Should I name the component NavMenuComponent instead? both seem weird to me. In this case the component only calls connect to get 1 field from the state. Is it really so bad to just inline the call to connect like this?
Curious to hear your thoughts @gaearon on when (if at all) it's "ok" to just inline the connect call... |
It doesn't matter how you call it. Why not call it I don't understand the question about inlining. |
ok so for example. containers/NavMenu
option 2 (1 single file containing both):
what I mean by inlining is just having a single file (as opposed to 2 files) which is both the container and the component since there's only the 1 little bit about the currentPath that's needed from state. Is this just something that should always be avoided or is it reasonable to do it in simple cases like this? |
Sure, it's reasonable to do this in simple cases. |
ok cool. when would you draw the line and say "ok I'd move this into 2 separate files"? |
When the component starts to mixes data concerns (how to retrieve / calculate data, how to dispatch actions) with presentation (how it looks). When it becomes hard to test or reuse in different context. |
@benmonro One more thought. If you're building a module of components, you would sometimes want to connect these components to different parts of your app's state tree, or test their presentation separately with various states. In this case, having |
thanks @gaearon @sompylasar very good point! thanks |
hmm ok after going through my code to refactor it to split it out, I now have a follow up question. suppose that I also have a |
I would make the NavMenuItem a pure presentational component with all needed data passed into it via props by NavMenu. This would allow to test it separately. So, you would have two presentational (NavMenu, NavMenuItem) and one connected ( connect(...)(NavMenuItem) ) component. |
A thing I'm missing in this discussion: When you have them in one file, you can't use shallow rendering for testing. I've seen people expose both the presentational component and the container component to work around this, and test then separately, so in this case I'd rather have two files to make it explicit that these are two things. This also highlights the separation of concerns here and the fact that the presentational component is independent and reusable. |
FWIW I updated the Presentational and Container Components article to reflect my current thinking. |
We no longer discourage creating container components in the updated docs. |
@gaearon in your actual example in the Redux doc seems that components can have containers as child. I have an app that render a Simple Data List component (Dumb). It's ok according to the doc, but can it bring some problem? Thank! |
This does make testing a little harder to set up (you need to initialize the store as well). When this is an inconvenience, extract more presentational components that accept |
Ok, so there's no right way. We have to evaluate case by case.. Many Il lunedì 8 febbraio 2016, Dan Abramov [email protected] ha
Luca Colonnello |
What about 'layout components'? I mean when you have many containers that need to be in a single component to pass it to the router/navigator, this wrapping component is going to be a 'dumb presentational container of containers' right? |
@Emilios1995 I have the same issue... However, if I try to pass to layout the menus and the header, i have a page (container) that render layout (component) and passing to it menus and header (containers). Doing this the hierarcy is correct, but I have to repeat menus and header in every page, and bith of them are the same in every page for me.. |
@LucaColonnello I don’t quite understand the issue without the code. May I ask you to create a StackOverflow question with a simple example illustrating your problem? I’d be happy to take a look. |
ASAP Il sabato 27 febbraio 2016, Dan Abramov [email protected] ha
Luca Colonnello |
@gaearon It's not an issue, I think it's rather a question which I've made here: http://stackoverflow.com/questions/35729025/should-the-route-handlers-use-containers-or-presentational-components?noredirect=1#comment59133192_35729025 |
I think Dan's article on medium 2016-03-01 18:19 GMT+01:00 Emilio Srougo [email protected]:
Luca Colonnello |
@gaearon I wonder that if a presentational component may contain container components inside, how can it be reusable? |
If all its usage scenarios include a specific container inside, I don’t see what’s not reusable about it. And if not, make it accept |
@gaearon Is [Root component] container component on React-Router?
Thanks. |
@gaearon above you said that you prefer to connect components in order to gain access to dispatch (as opposed to passing it down through from parent components). If you connect these components, and they also have props which could be mapped from the reducers which are currently being passed in by the parent, would you refactor these to come from Is there a functional/performance difference between the two options? |
I don't have much experience working with huge redux projects but I've been researching and thinking a lot about optimizing react/redux file structures. Let me know if this makes any sense or not:
another concept:
Or is it just better to keep components, containers and redux modules separate (even though they share the same name)? Thanks for any input. |
I have worked with enterprise level react-redux projects and through my experience, I can say one thing that it solely depends on you how to define the architecture of your project. I don't follow any of the container/component based architectural variations because they are impractical in the sense that React's purpose is to make reusable components based UI. So I have come up with a simple approach of grouping entire projects based on Modules and it has worked really well till now in terms of scalability, maintainability, and code readability. For me, container and smart-component are exactly the same. The simple definition is: |
In the examples there are always a folder called "container" and one called "component". What is the thought behind this separation?
Are "containers" smart component or are they route components or something else? Should components under "components" always be dumb?
The text was updated successfully, but these errors were encountered: