In the getting started video of Redux we see that the Footer (a dumb component) uses Filterlink (a container).
But when I read this article, it seems, but not very clearly, that only containers should use/render containers.
For me, if Footer uses Filterlink (which is tied to Redux) I can't reuse it on other projects which don't use Redux. But maybe it is an exception? Maybe hard coding dumb component for use only on one project is ok?
Am I missing something?
The article was somewhat out of date with how I think about it today. I just updated it so you can read it again with the fresh perspective. I’ve come to the opinion that it’s totally fine to use container components inside presentational components. The reason for this is simple: you want to be able to turn a presentational component into a container component at any time it needs too much information, and it would be a bummer if you had to convert all call sites when you do that. Therefore whether a component is presentational or a container is its implementation detail, and any components, whether presentational or containers, can use it just fine.
Related
I'm struggling about what may be a good way to implement components in React with a good coding pattern.
Normally I know the idea of presentational and container components: the presentational only shows html and receive everything from props (data and callbacks); the container orchestrate the presentationals retrieving and mutating data and passing it to them by props.
Now I'm using redux with redux toolkit and rtk query, with hooks.
Following that approach, the container component should be the only one allowed to useSelector and useDispatch and useQuery. But I find a lot easier and cleaner allowing the presentationals to select and fetch and dispatch what they really need, instead of making a giant container component which manage all the data for its children with a huge list of state and fetch access. This is true especially for lists, where it is a lot easier and cleaner just letting each child to retrieve its own data (fetched or from state), or for deeply nested presentationals.
However I'm mixing up container components with fake presentationals which anyway retrieve something when it is easier and true presentationals maybe for general and totally reusable components. Also the components tree is very messy (like container->fake presentational->container->fake presentational->true presentational->true presentational ...).
At the end I feel like I don't have good rules and the code is messed up.
Are container and presentation components still a good coding style which follows a best practice pattern but in the world of hooks and redux?
The React Container Pattern advocated by Dan Abramov has for all intents and purposes been deprecated since the introduction of React hooks in 2018.
See Dan's blog entry Presentational and Container Components from 2015.
His update from 2019:
Update from 2019: I wrote this article a long time ago and my views
have since evolved. In particular, I don’t suggest splitting your
components like this anymore. If you find it natural in your codebase,
this pattern can be handy. But I’ve seen it enforced without any
necessity and with almost dogmatic fervor far too many times. The main
reason I found it useful was because it let me separate complex
stateful logic from other aspects of the component. Hooks let me do
the same thing without an arbitrary division. This text is left intact
for historical reasons but don’t take it too seriously.
With the advent of React hooks the distinction between "smart" and "dumb" components, and "container" and "presentational" components, was all but eliminated.
The common pattern and "best practice" now is to write React Function components and just use the React hooks. In the case of using Redux and React-Redux, the useDispatch and useSelector hooks instead of the connect Higher Order Component. I've not gone out of my way to write a React Class component or split my code between "presentation" and "container" since the advent of React hooks.
My rule of thumb is to do it all in one component. Then as you create more and more components you'll see patterns start to emerge. So instead of copying and pasting code from component to component you can make a presentational component that takes in props for what to render. Some of those props can even be what to do when a button is clicked or a box is checked.
Overall your presentational components will end up resembling something like one of the various react js ui frameworks out there such as https://mui.com/
I'm new to React Native and new ish to starting my own projects from scratch. What are some best practices to document what each prop type does and which prop types are required for custom components I'm creating?
It's fresh-in-mind when I've build the component and know how the props behave that day. Yes, it might be able to be observed by parsing through the code where the function components were defined, but I'd like to make it as easy as possible to easily access and know at the time of calling and using the Component.
If a future developer or myself in 1 week+ comes back and wants to use these components, the experience of seeing what props are possible and what they do should be accessible.
Any ideas of how you like to navigate documentation best practices like this? Love improving the developer experience :) Thanks!
Let's say that I'm fetching some images from an API in the App component.
Then I want to pass it to the component responsible to rendering images. But this component is not a direct child to the App component. It is the child of a direct child of App component.
Here's how I would pass the images array down to the image component, but I feel like it might not be the best approach.
But what would happen if this hierarchy gets more complex - even just by one more component:
Intuitively, it might not be the best thing.
So, what would be the best way to pass the images array down to the image component, if there are many other children between them?
The problem is usually called Prop Drilling in the React world: https://kentcdodds.com/blog/prop-drilling
A few options:
Passing props may not be that bad. If the app is small, is a very modular -and easy to unit test- option . You can reduce the verbosity by using prop spread: <Comp {...props} /> and by keeping your component interfaces similar. (many people dislike prop spreading as you can unintentionally pass unsupported props, but if you use TypeScript the compiler will catch that).
You can use a React Context: https://reactjs.org/docs/context.html (as other mention in the comments). However, keep an eye on how your context objects are defined (keep them small). React will re-render all the childs using the context when the value changes, is not smart enough to automatically detect changes at the property level. Frameworks like Redux or Zustand use other mechanisms to allow a granular control of the shared state (you'll see examples of a useSelector hook).
You can also take a look to a state management framework (Zustand is my favorite, but Redux is more popular). However, it may be an overkill for small things.
My personal choice is to start with prop drilling, it's easier to modularize and unit test. Then you can think on your app in layers: upper layers depend on a context (or a state framework), and lower layers receive properties. That helps when you want to refactor and move reusable components to other projects.
I'm quite new to React, and I'm making a single page application with React.
So far, I've build the application with components and child components, having their own local state, however the child components doesn't really interact with one another, which is what I want them to, basically, with the least amount of boiler plate code...
The problem I'm facing, is that a change in some child component, should be able to update the state of another child component, somewhere else in the component tree.
A selection in one child component should also be able to trigger a function in another component updating it with data and so on.
I've considered having just one global application state, that all components can call and update when something in them changes, and this one application state will then update other components in the tree. Kinda like having a single "controller" with it's own state, that all components "views" can call, and which updates the states of other components as needed. (I'm used to WPF and MVC style of GUI programming).
What I've considered:
One could try to implement this with callback functions defined in the top of the hierarchy, to be sent down through the hierarchy and called from a child component when it changes.
This method however results in a LOT of boilerplate code that just passes functions to their child components. It feels wrong and hard to maintain...
To avoid all this passing around and boilerplate code, I've tried using a React Context, however this is not working as well as I hoped. I can only access the context from within the render function and from lifecycle functions, and sadly I often get complicated errors that are hard to understand. It seems like I'm exploiting React Context to do something you shouldn't use it for...
I've considered using a singleton pattern in JavaScript, however then that singleton needs to have a reference to the root component, and query for the component it needs to change... This seems like kind of a hack, and may not be that pretty, but idk.
I'm considering trying out React Redux however it seems to work in many ways similar to React Context (I'll be honest, I haven't read much into it yet).
What I need:
I need to ask someone with greater React experience than me: How do you keep a global application state, and update child components based on changes to the global application state? Also: Am I thinking about this all wrong? Am I trying to do something in a non-react way, failing to see how I should do it in React?
You can happily go with Redux or MobX, they're fine.
I suggest Taming The State from Robin Wieruch: https://roadtoreact.com/course-details?courseId=TAMING_THE_STATE
There are the book and the course. He shows different ways of handling React state.
Redux was created specifically for the problem yo stated.
Reacts follows a top-down down-top unidirectional flow in essence. Context API is useful in simple use cases but would fail horribly in a large scale application where you'd be creating consumers everywhere.
I'd suggest investing some time in Redux so that will save your precious time in long run.
There's a reason all big three frameworks require a state management library to be useful for large scale complex apps. (Angular has NgRx and Vue has Vuex).
I was wondering something about the reverse data flow in a React app.
Considering this question: data flow in react application and this article http://facebook.github.io/react/docs/thinking-in-react.html
We can see that the "normal" way to communicate from child to parent component is using callback passing through this.props.myCallback. (the StackOverflow article is a good example)
My questions are:
I understand the concept but what if we have deeper components? We would have to pass this callback to every component between the top parent component who hold the state and the actual triggering component. And if there is 3 to 4 components between them, I would have to pass the callback using this.props in each component.
Why not using an Event Emitter? I could send an event from the deep child component and then listen to this event in my top state parent component. This way we could avoid all the code between these two.
Please tell me what are your thoughts about this!
I learnt the hard way that it is a good practice to keep as much logic as possible in the highest level in the hierarchy of your components. Dan Abramov well expressed this idea in the article Smart and Dumb Components, where Smart Components are those that hold the logic, whereas Dumb Components are just meant to display.
So yes, the callback mechanism works well when you simply want to update the father's state, or you want the father to do an action whose logic you do not want to belong to the child.
When you have anything slightly more complicated than this I would suggest you go with a Flux-ish architecture of your taste. Flux indeed uses node's EventEmitter to communicate with the components.