Photo by on Kris Guico Unsplash There are so many best practices and advanced patterns — the problem is keeping track of them and keeping them in mind as you develop new components. I wrote this checklist to help myself remember all of the things I need to be thinking about as I go through building highly reusable components. This checklist applies equally to both Vue and React. Really, it doesn’t matter which framework you use, since the principles of component composition . And the general process for designing a component doesn’t change either. are exactly the same Condensed checklist at the end of the post. Avoid speculative generality This one sounds pretty obvious, but I find myself forgetting this all the time. You need to fully understand use case, and only implement that. If you just dive into code without thinking first, you’ll end up writing in a bunch of features that will never be used. That’s a of your precious time. your colossal waste When writing a component that is supposed to be reused across many different use cases, the temptation to provide more and more abstraction is easier to justify. However, if you write the component well, it should be fairly easy to come back later and add in new use cases you couldn’t anticipate. This is where comes in handy. A few of the features you implement will be responsible for handling most of the use cases. Focus on those. 80/20 thinking I’ll leave you with one last tweet about API design: Simplify the API Now that we’ve stopped to think, let’s simplify our API as much as possible. You’re also trying to find the sweet spot between simplicity and flexibility. As said in : Ken Wheeler A Bitter Guide to Open Source You want to find the perfect balance of working out of the box, and configuring as necessary. On top of that, you want to keep things clear, explicit and approachable. Don’t be too clever or you will piss everyone off. Too simple and it doesn’t cover enough use cases to be helpful. Too flexible and it becomes too difficult to understand how to do anything. Just take a look at how many options this has. It’s terrifying! jQuery Datepicker This is where more advanced composition patterns really come in handy. Typically you’re making trade offs between simplicity and flexibility. But techniques like and allow you to achieve render props compound components more flexibility while reducing complexity. Research prior art We have a pretty good idea of what we we’re building now, but first we need to see what else is out there. There are a few reasons for this: First, we can for our implementation. get great ideas If we look at mature open source projects, they will be more or less feature complete. This lets us double-check our assumptions about what we might need to build out. We can also see how the API was built, what abstractions were used, and possibly even some implementation details we wouldn’t have considered. Second, we can potentially . save ourselves some work There’s a good chance we’ll find something that we can use to speed up development. We may even find something that ticks all our needs, and end up short-circuiting this whole process. In his , mentions that he likes to check out jQuery plugins. They’ve stood the test of time, and likely have all the features that you’d ever consider putting in a UI element. Advanced React.js course Ryan Florence A great place to start is in the Awesome repos: Awesome-React Awesome-Vue Break up components into bite-sized pieces Compositional frameworks use components as their main technique of abstraction (vs. objects in OO or functions in functional programming). If you shove everything into one or two giant components, you aren’t taking advantage of this at all! Smaller components are better: Better abstraction makes your , easier to understand, and easier to maintain code cleaner Encourages of the code reusability Necessary in order to use more fancy-pants composition techniques advanced There are a couple main ways to think about splitting up components: Isolating behaviour from presentation You have in one component, with a separate component responsible for rendering. We would typically do this through render props and stateless functional components. state and logic Levels of abstraction It’s often a good idea to keep the level of abstraction consistent within a component. Either the component would deal with native DOM elements, like , , , or it would deal with framework components. div p span Just be careful, because you don’t want to go overboard and create ! has a great article on . too many components Kent C. Dodds how to know when things should be split up Use powerful composition patterns — only where needed Render props, provider pattern, higher order components. These patterns are seductive and fun to use. But they are not always the right tool for the job. Knowing when to use each one to it’s maximum effect is important. Otherwise for the job and dig yourself into a hole. you may use the wrong tool If you want to learn more about these, I highly suggest checking out Kent C. Dodd’s article on : advanced patterns in React Compound components Break up parts of your component into smaller bits that can be recombined in different ways. For example, take your component and break it down into , , and components. Most people will be fine to use the regular , but now someone can build their own table and build a custom header for it without too much trouble. Table TableHeader TableBody TableFooter Table Higher order components Take a component and wrap it up inside another component to to it. This concept evolved from the object-oriented idea of mixins, but has largely replaced it (although Vue still has supports mixins). add functionality When React first came on the scene, mixins gave developers an escape hatch, allowing them to go back to something familiar from the object-oriented world. After awhile we figured out that so higher order components became the norm. composition is far better than inheritance, Render props and renderless components Now we’re seeing another shift. This time away from higher order components, and towards what are called (or render props function as children). Render props let us to the parent component, giving us even cleaner separation between behaviour and presentation. If you combine this pattern with the prop getters and setters pattern, you can build incredibly flexible and expressive components with very few lines of code. delegate rendering Controlled and uncontrolled props Does the component control the state, or does it’s parent control the state? That is the difference between an uncontrolled and a controlled prop. Generally, uncontrolled props are used since they allow us to encapsulate complexity and state within the component. However, if you want more flexibility — which we need when writing a highly reusable component — you can allow a prop to be controlled by the parent. State reducer This is a pattern I learned from Kent C. Dodds in his project ( ). Downshift more explanation here If you’re going to expose a prop to be controlled, why not expose the entire state reducer? Then over the behaviour of the component — but you don’t have to re-write any logic. you can have extremely fine-grained control Brilliant. Provider pattern If you’ve used Redux or VueX or something similar, you probably know this pattern. Instead of passing props around all day long, and passing them down through many many levels of components, you simply “inject” them where they need to be. In React this can be done , or in Vue. using context provide and inject Accessibility is not an afterthought I’m not very good at accessibility yet. It’s something I’ve been getting better at recently though, because I believe to making the web a better place. it’s incredibly important Since I’m not an a11y expert, I’ll instead get you to read this article wrote on . You can also check out the great resources of . Addy Osmani developing accessible web components The A11Y Project _To be accessible, UI components need to work across multiple devices with varying screen-sizes and different kinds of…_medium.com Accessible UI Components For The Web Make it easy to style How easy is it for consumers to the way they need? style your component The intention is that your component will be used all over the place. In all sorts of wild and various contexts. It will be used in ways . you could never have imagined even in your weirdest dreams You need to make sure that other devs can easily style and change the layout of your component without resorting to ugly CSS overrides. Renderless components make this super simple. You can just to whoever is using your component. delegate all rendering However, in many cases it’s useful to render something by default. A good approach here is to and provide CSS classes that can be easily overriden. use BEM in your component But CSS isn’t Turing complete! Alternatively, you can take the and use CSS-in-JS (it’s not for everyone). cool-kid approach When this idea started out, most libraries were implemented using inline styles. This caused some performance issues and had some other issues as well. Nowadays, most libraries work by to the DOM, and the biggest issues have been resolved. I haven’t had a chance to dive into these in awhile, but it’s on my list! dynamically attaching stylesheets There’s tons of libraries, talks, and articles out there about this if you want to learn more, but , and . here is a good place to start for React here for Vue Do you even test, bro? You don’t want tons of people using your beautiful new component, only to have it flake out on edge cases. Or heaven forbid you add a slick new feature — but it breaks everything else. When you’re building a reusable component like this you probably won’t do any integration or end-to-end testing. You’ll be writing that focus on testing tricky logic and making sure the component is rendering properly. unit tests Here are a few great articles on testing React and Vue components if you need to get started: _Test suites are an upfront investment that pay dividends over the lifetime of a system. Today we'll introduce the topic…_www.fullstackreact.com Fullstack React: Introduction to Testing _Vue.js has become the framework of the year. It's very flexible, performant and easy to learn that lead to a massive…_alexjoverm.github.io Unit Testing Vue.js Components with the Official Vue Testing Tools and Jest | Alex Jover Morales Documentation — It’s what makes all the difference “I’ll write the docs later”, you think to yourself as you push the last beautiful crafted commit to Github. “I mean, even if I don’t get to it .” no one will really care After all, you’re a professional at writing in , not one of these “ ” languages that humans speak. Javascrip t natural But great documentation is what turns a good component into . a great component You know the feeling when you’re trying to figure out how to get a library to do something, or you get confused about React’s (or Vue’s) lifecycle methods. If you can’t find the answer quickly, it’s super frustrating. Sometimes you’ll even get rid of the library because how to get it to work! you can’t figure out Don’t let your shiny, brand new component to go to waste because of a lack of good documentation. Condensed Checklist Now that we’ve gone through all of that, here is the easy-to-reference version: Avoid speculative generality Simplify the API Research prior art Break up components into bite-sized pieces Separate state + behaviour from presentation Split up by level of abstraction Use powerful composition patterns — only where needed Compound components Higher order components Render props and renderless components Controlled/Uncontrolled props State reducer Provider pattern Accessibility is not an afterthought Make it easy to style Do you even test, bro? Documentation — It’s what makes all the difference Check out my articles as soon as they come out at michaelnthiessen.com ! I re-post them here a few weeks later.
Share Your Thoughts