{"id":20443,"date":"2020-07-09T10:30:59","date_gmt":"2020-07-09T09:30:59","guid":{"rendered":"https:\/\/blog.marvelapp.com\/?p=20443"},"modified":"2020-07-20T17:18:26","modified_gmt":"2020-07-20T16:18:26","slug":"making-good-component-design-decisions-in-react","status":"publish","type":"post","link":"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/","title":{"rendered":"Making good component design decisions in React"},"content":{"rendered":"<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Most of us who are using React love it for its declarative nature and how it encourages us to think about complex applications as a composition of multiple UI components.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">However, as developers, we don\u2019t always spend enough time to think about our component design and how components will scale and change with our application. At one point, you might start noticing massively complex pieces of code across your codebase and wonder what\u2019s going on. In fact, if you have worked on a project long enough you might not even realize there\u2019s a problem, until a fellow team member asks to be walked through a certain piece of code.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Imagine you are both looking at a complex component that is part of a feature that needs to be extended. You might find that reading and understanding the code requires carefully following different props to get an idea of how user interaction changes the data this component receives. On top of that, you might also need to follow those same props in some wrapping parent component (just one level up, if you are lucky) to determine where the state of each prop is, and how that data is then used, for example, by an API.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">If you have been in a situation where reasoning about a particularly complex component produced some discomfort or confusion, it is good to realize that this is likely a side effect of component design being an afterthought, rather than a crucial step in UI development. So why don\u2019t we care more about component design?<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><img class=\"size-full\" title=\"\" alt=\"\" \/><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1Gt1KT_haQIFwyAR95_AlDg.jpeg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-6580\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1Gt1KT_haQIFwyAR95_AlDg.jpeg\" title=\"\" alt=\"\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Every codebase has its complexities. Building a product and quickly delivering features to users brings more value to your team (and business) than having over engineered solutions. The nature of React lets you quickly compose with reusable components and add missing functionality by passing a couple of more props, but it is our responsibility as engineers to consider solutions and approaches that are resilient to change and assume that our products will evolve. The future of the product and good component design should be on your mind, but it is often forgotten. Sometimes it\u2019s hard to wrap your head around how to translate a visual design or a requirement to a functioning, testable React component. Perhaps the feature you\u2019re about to build seems complex or maybe you\u2019re dealing with a component that seems to have a lot of responsibility. Or maybe you struggle seeing how an existing component that is already overloaded with tens of props can be extended or reused in your app.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Here is one approach that I like to follow when thinking about the design of my components early in a feature\u2019s lifecycle.<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">Thinking of components in isolation<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Let\u2019s think about React components in general terms. React components are functions. Regardless of <em>how<\/em> you implement a specific component \u2014 as a class or as a function \u2014 your component probably takes some props as arguments and returns JSX that describes what would eventually be rendered in the DOM. With React, we aim for writing our components as<a class=\"link link--blue fontWeight-4\"href=\"https:\/\/reactjs.org\/docs\/components-and-props.html\"> <em>pure functions <\/em>with respect to their props<\/a>. Meaning, for any given set of props, our components should return the same JSX.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Following the Single-responsibility principle, a function \u2014 and therefore a React component \u2014 should be doing one thing. For example, a component that only renders a user\u2019s avatar given an image URL would be considered a component that follows this principle. On the other hand, the principle would be considered broken if you have a component that renders a user\u2019s avatar if it exists, and calls an API to generate a random image if it doesn\u2019t.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Thinking about React components in isolation and identifying the role each component plays on its own will keep you from writing overly complex, multi-purposed code. Pure components with a single responsibility means less props which, in turn, yields a component that is easier to test and easier to reason about.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">With this in mind, how can we actually determine <em>what<\/em> the responsibility of the component really is? And how can we keep it resilient to change?<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">Thinking in terms of \u201cvalue\u201d &amp; \u201conChange\u201d<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">We saw that we can generally think about UI components as functions that take some data and return a visual representation of that data. We can think about a simple input component in a similar way. A text input component (an input with a type=\"text\" attribute) takes a string as its data and renders an input field with that value. Similarly, a checkbox input component takes a boolean and renders a checked or unchecked box. You might notice that an input field and a checkbox represent different data types \u2014 a string and a boolean respectively. Understanding this can help you approach the design of your own components in a different way.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Imagine you are working on a new input component for shopping items which will be used within a larger shopping form. It should look like this:<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><img class=\"size-full\" title=\"\" alt=\"\" \/><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1EmhgRczdshj8l-NJoBQIcA.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-6580\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1EmhgRczdshj8l-NJoBQIcA.png\" title=\"\" alt=\"\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">The user interacting with this component should be able to type in items into the field and every item that\u2019s added should be shown as a little label. The user can then keep on adding more items or remove any existing item by clicking the \u201cx\u201d button on the label. It should also be possible to clear all the labels by clicking \u201cclear all\u201d.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Take a moment to think what data type this component represents? How will the component change that data over time?<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">You might notice that this component represents a list of strings \u2014 the shopping items the user has added. A good way to represent this data is simply by using an array of strings. I like calling this the component\u2019s <strong class=\"c-slate lineHeight-l fontSize-l fontWeight-5 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><em>value<\/em><\/strong>.<\/p>\n<div id=\"attachment_20449\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/gist.github.com\/ablamunits\/df864f0af2f0678c79e865014bc2ff87#file-value-on-change-ex1-tsx\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20449\" class=\"wp-image-20449 size-full\" title=\"A shopping form component that uses our new input component \u2728\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1.png\" alt=\"\" width=\"720\" height=\"277\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1.png 720w, https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/1-600x231.png 600w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><p id=\"caption-attachment-20449\" class=\"wp-caption-text\">A shopping form component that uses our new input component \u2728<\/p><\/div>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">For simplicity, let\u2019s keep the shopping items as strings. In a real-world application individual items in this kind of use case can be more complex, but the same principle still applies.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">The next thing to consider is the changes the component can make to its value. We mentioned in the requirements that this component should allow adding &amp; removing individual items, as well as having a \u201cclear all\u201d functionality. You could choose the following approach:<\/p>\n<div id=\"attachment_20450\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/gist.github.com\/ablamunits\/ff7888ae1dc40b014c4f4e5a195a9522#file-value-on-change-ex2-tsx\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20450\" class=\"wp-image-20450 size-full\" title=\"Passing multiple callback props to InputWithLabels. This is what we want to avoid.\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/2.png\" alt=\"Making Good Component Design Decisions in React\" width=\"720\" height=\"626\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/2.png 720w, https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/2-600x522.png 600w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><p id=\"caption-attachment-20450\" class=\"wp-caption-text\">Passing multiple callback props to InputWithLabels. This is what we want to avoid.<\/p><\/div>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">You might have noticed that in this example, as well as the first one, I have omitted the implementation code for the InputWithLabels component. Regardless of its implementation detail, designing InputWithLabels such that it uses multiple callback props comes with some downsides. The first problem that arises is prop bloat. The complexity of the component increases solely by the fact that it requires 3 callback props to perform its duty. The second problem is that the parent component (in our case that\u2019s ShoppingForm) is responsible for updating the data each time any of the callback props are called, and before persisting that in its state. This means that if InputWithLabels is reused elsewhere, that logic will need to be re-implemented.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Remember that our component\u2019s <em>value<\/em> is an array of strings. Instead of having individual props for each required functionality\u2019s handler, let\u2019s focus on how our <em>value<\/em> is changed by the component depending on its different functions:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>When a label is added, a new string is added to the strings currently in the value array.<\/li>\n<li>When a label is removed, a string is removed from the value array.<\/li>\n<li>When clicking \u201cclear all\u201d, all items in the value array are removed.<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">We can see that given the required functionalities we are able to describe the changes made to our <em>value<\/em>. Therefore instead of having individual multiple props on our InputWithLabel component, we can use a single callback prop. I call this the component\u2019s <strong class=\"c-slate lineHeight-l fontSize-l fontWeight-5 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><em>onChange<\/em><\/strong>.<\/p>\n<div id=\"attachment_20451\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/gist.github.com\/ablamunits\/137238dff4ed2c9f8beb663a1f64d359#file-value-on-change-ex3-tsx\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20451\" class=\"wp-image-20451 size-full\" title=\"The logic for handling the value change becomes the responsibility of our component\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/3.png\" alt=\"The logic for handling the value change becomes the responsibility of our component\" width=\"720\" height=\"795\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/3.png 720w, https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/3-543x600.png 543w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><p id=\"caption-attachment-20451\" class=\"wp-caption-text\">The logic for handling the value change becomes the responsibility of our component<\/p><\/div>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">The function passed to the onChange prop will be called with the updated value whenever it needs to change. This way, the parent component is not aware of the implementation detail (<em>how<\/em> the value is changing). It can assume the data is correct and just update the state, call an API or do other \u201c<em>smart\u201d<\/em> things. Any other component that uses InputWithLabel can make the same assumption and does not need to re-implement the same logic over and over.<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">Why this matters<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">By thinking about our component\u2019s <em>value<\/em> and <em>onChange<\/em>, we are able to describe the data structure that best represents our component, as well as how the component is changing over time. Following this approach helps design components with a predictable data flow, making the purpose of your components in a complex app easier to understand and reason about. As your application changes and grows and you build your app on top of components that are designed this way, extending functionality becomes a question of supporting a new change to the component\u2019s value, or changing the value\u2019s data structure if appropriate. Equally as important, it enables you to promote a consistent code style across your entire app \u2014 focusing building components around two main props, which can prove particularly valuable when building design systems.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Unit testing UI components in isolation becomes trivial as well. Because we are treating our component as a function of value and onChange props, it is easy to write tests that assert an onChange callback is called with an expected value based on interactions with our component.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Lastly, I find that this approach shines even brighter with <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a>. For every component you build, you could explicitly specify types for value and onChange, or alternatively, create a reusable generic type to use with all of your components following this pattern:<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/gist.github.com\/ablamunits\/52fe478d5bedff237b83f2359d9ceb0c#file-value-on-change-ex4-tsx\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-20452 size-full\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/4.png\" alt=\"alternatively create a reusable generic type to use with all of your components\" width=\"720\" height=\"349\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/4.png 720w, https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/4-600x291.png 600w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Of course, as with anything, this is not a silver bullet solution for all of the problems you might encounter. There will be cases where this pattern would not fit at all or components where additional props on top of value and onChange are totally justified \u2014 like search fields or paginated lists. This is just one approach to component design and there are other well-documented approaches and patterns, each being valid for different classes of problems. It is up to you and your team to gradually build your approach as your product grows, and stay mindful to how your code changes as your product complexity grows.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Enjoy coding!<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">. . .<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Originally published on <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/medium.com\/@ablamunits\/making-good-component-design-decisions-in-react-2f4972e55d5\">Boris' Medium<\/a> page<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Making good component design decisions in react when it&#8217;s hard to see how an existing component can still be reused<\/p>\n","protected":false},"author":344,"featured_media":20453,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[472],"class_list":["post-20443","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-viewpoint","tag-front-end-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v15.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"description\" content=\"How to make good component design decisions in react when sometimes it&#039;s hard to see how an existing component can still be extended or resued in your app.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Making good component design decisions in React\" \/>\n<meta property=\"og:description\" content=\"How to make good component design decisions in react when sometimes it&#039;s hard to see how an existing component can still be extended or resued in your app.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/\" \/>\n<meta property=\"og:site_name\" content=\"Marvel Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/marvelapp\" \/>\n<meta property=\"article:published_time\" content=\"2020-07-09T09:30:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-07-20T16:18:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/87.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"700\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@marvelapp\" \/>\n<meta name=\"twitter:site\" content=\"@marvelapp\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"7 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\",\"name\":\"Marvel\",\"url\":\"https:\/\/marvelapp.com\/blog\/\",\"sameAs\":[\"https:\/\/www.facebook.com\/marvelapp\",\"https:\/\/www.instagram.com\/marvelapp\/\",\"https:\/\/www.linkedin.com\/company\/marvel-app\/\",\"https:\/\/twitter.com\/marvelapp\"],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#logo\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/marvelapp.com\/wp-content\/uploads\/2018\/06\/Logo-Light.png\",\"width\":1605,\"height\":1130,\"caption\":\"Marvel\"},\"image\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#website\",\"url\":\"https:\/\/marvelapp.com\/blog\/\",\"name\":\"Marvel Blog\",\"description\":\"Ideas and words on user experience, design, collaboration and more\",\"publisher\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/marvelapp.com\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#primaryimage\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/marvelapp.com\/wp-content\/uploads\/2020\/07\/87.png\",\"width\":1600,\"height\":700,\"caption\":\"Making good component design decisions in React\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#webpage\",\"url\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/\",\"name\":\"Making good component design decisions in React\",\"isPartOf\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#primaryimage\"},\"datePublished\":\"2020-07-09T09:30:59+00:00\",\"dateModified\":\"2020-07-20T16:18:26+00:00\",\"description\":\"How to make good component design decisions in react when sometimes it's hard to see how an existing component can still be extended or resued in your app.\",\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#webpage\"},\"author\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#\/schema\/person\/e609295d0c2bde3bea7aed4544d721a0\"},\"headline\":\"Making good component design decisions in React\",\"datePublished\":\"2020-07-09T09:30:59+00:00\",\"dateModified\":\"2020-07-20T16:18:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#webpage\"},\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#primaryimage\"},\"keywords\":\"Front End Development\",\"articleSection\":\"Viewpoint\",\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/marvelapp.com\/blog\/making-good-component-design-decisions-in-react\/#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#\/schema\/person\/e609295d0c2bde3bea7aed4544d721a0\",\"name\":\"Boris Ablamunits\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#personlogo\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a944c75be8a7b0f0ae4da3f898b18f57c1361627e65393fecc5bbeb1d62957d6?s=96&d=mm&r=g\",\"caption\":\"Boris Ablamunits\"},\"description\":\"Frontend Engineer at Marvel\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","_links":{"self":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts\/20443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/users\/344"}],"replies":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/comments?post=20443"}],"version-history":[{"count":0,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts\/20443\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/media\/20453"}],"wp:attachment":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/media?parent=20443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/categories?post=20443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/tags?post=20443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}