{"componentChunkName":"component---src-components-posts-layout-index-js","path":"/react-components-are-just-functions/","webpackCompilationHash":"6fd724ef40842b910a04","result":{"data":{"mdx":{"id":"8394b154-b689-534b-9363-c527e09d8433","timeToRead":3,"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"React Components are Just Functions\",\n  \"date\": \"2020-12-16\",\n  \"excerpt\": \"When developing React components it's easy to think of them as their own beast. It's important however to realize that they are just an abstraction over regular javascript functions.\"\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"When developing React components it's easy to think of them as their own beast. It's important however to realize that they are just an abstraction over regular javascript functions.\"), mdx(\"br\", null), mdx(\"h2\", null, \"What is React?\"), mdx(\"p\", null, \"React components are the low level building blocks that make up a react application. So to understand what components are, let's first understand what react is.\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"React is a declarative, efficient, and flexible JavaScript library for building user interfaces. - \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://reactjs.org/tutorial/tutorial.html\"\n  }), \"React Docs\"))), mdx(\"p\", null, \"Here's a basic React component:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"function Hero() {\\n  return (\\n    <div>\\n      <h1>Hi, I'm Dillon!</h1>\\n      <p>This is my react component</p>\\n    </div>\\n  )\\n}\\n\")), mdx(\"p\", null, \"Our markup in the middle is React's templating language called JSX. It's important to note that JSX is simply an abstraction that sits above the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method exported from React. This is what the above code looks like without utilizing the JSX abstraction:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"return React.createElement('div', null,\\n  React.createElement('h1', null, \\\"Hi, I'm Dillon!\\\"\\n  React.createElement('ul', null, \\\"This is my react component\\\")\\n);\\n\")), mdx(\"p\", null, \"As you can see, the JSX in our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" component is really just syntactic sugar for calling the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method exported by React. Let's take a closer look at \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" 's \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Glossary/Signature/Function\"\n  }), \"function signature\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"React.createElement(component, props, ...children)\\n\")), mdx(\"p\", null, \"Now let's break down each of the arguments this nifty function named \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" accepts.\"), mdx(\"br\", null), mdx(\"h2\", null, \"Component\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"React.createElement(component, props, ...children)\\n\")), mdx(\"p\", null, \"The first argument, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"component\"), \", takes a string representing any native HTML elements (ex. \\\"div\\\", \\\"h1\\\", \\\"p\\\" etc.). This is what we did in our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" example. You can also pass plain old javascript functions as an argument for component. The fact that the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method can take in a javascript function is a key point here. More on that to come, first let's take a look at the 2nd argument, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \".\"), mdx(\"br\", null), mdx(\"h2\", null, \"Props\"), mdx(\"p\", null, \"The second argument we pass to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" is props. Props is just a plain javascript object. From the React Official Documentation:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"When React sees an element representing a user-defined component, it passes JSX attributes and children to this component as a single object. We call this object \\u201Cprops\\u201D.\")), mdx(\"p\", null, \"In our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" example, we didn't include any attributes to our JSX elements, therefore props was null. We'll take a look a closer look at how props work in the next section.\"), mdx(\"br\", null), mdx(\"h2\", null, \"Children\"), mdx(\"p\", null, \"Children are the components nested inside of the JSX element. Let's look again at our example:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"function Hero() {\\n  return (\\n    <div>\\n      <h1>Hi, I'm Dillon!</h1>\\n      <p>This is my react component</p>\\n    </div>\\n  )\\n}\\n\")), mdx(\"p\", null, \"The children of this JSX element \\\"div\\\" are the \\\"h1\\\" and the \\\"p\\\" elements. Those elements also have children. The \\\"h1\\\" element has 1 child, which is the string \\\"Hi, I'm Dillon!\\\". The \\\"p\\\" tag also has 1 child, which is the string \\\"This is my react component.\\\" Now looking again at our transpiled version of this code:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"return React.createElement(\\n  'div',\\n  null,\\n  React.createElement('h1', null, \\\"Hi, I'm Dillon!\\\"),\\n  React.createElement('ul', null, 'This is my react component')\\n)\\n\")), mdx(\"p\", null, \"We can see that JSX is just a series of nested calls to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \". It's really 1 call to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" with nested calls passed as the third argument (children). In this example we are passing 'div' as the first argument, which can either be a string value of the HTML element you want to create, or a function. Next, we pass \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"null\"), \" as the value for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \" since we aren't passing any props to these elements.\"), mdx(\"br\", null), mdx(\"h2\", null, \"What are React components?\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"React components let you split the UI into independent, reusable pieces, and think about each piece in isolation.\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called \\u201Cprops\\u201D) and return React elements describing what should appear on the screen.\")), mdx(\"p\", null, \"Let's look again at our simple React component:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"function Hero() {\\n  return (\\n    <div>\\n      <h1>Hi, I'm Dillon!</h1>\\n      <p>This is my react component</p>\\n    </div>\\n  )\\n}\\n\")), mdx(\"p\", null, \"This isn't too interesting in that it's a function that takes no inputs and spits out some markup. Let's take a closer look at how props work to understand how our component becomes dynamic.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"function Hero(props) {\\n  return (\\n    <div>\\n      <h1>Hi, I'm {props.name}!</h1>\\n      <p>This is my react component</p>\\n    </div>\\n  )\\n}\\n\")), mdx(\"p\", null, \"In our h1 tag we are now accessing the property \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"name\"), \" on an object called props? Now how is this possible? What is props really and how do we have access to it here? This really has more to do with whoever is invoking \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" than \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" itself. Let's go one level up and see what happens when we invoke this component.\"), mdx(\"br\", null), mdx(\"p\", null, \"Let's say we are developing a marketing page. We have a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Home\"), \" page component and inside of it we want to render our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" component. That would look something like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"function Home() {\\n  return <Hero name=\\\"Dillon\\\" />\\n}\\n\")), mdx(\"br\", null), mdx(\"p\", null, \"If we transpile the return value, we should now know what to expect, a call to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"return React.createElement(Hero, { name: 'Dillon' })\\n\")), mdx(\"br\", null), mdx(\"p\", null, \"This is cool. Now, we are passing a value to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \"'s second argument, props.\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"When React sees an element representing a user-defined component, it passes JSX attributes and children to this component as a single object. We call this object \\u201Cprops\\u201D.\")), mdx(\"p\", null, \"So when this \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method is invoked by React, under the hood it is passing an object called props to our function \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \". That is why when we declare our component \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" , we can access the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"name\"), \" value from the props object that React so conveniently made available to us.\"), mdx(\"br\", null), mdx(\"h2\", null, \"Just functions\"), mdx(\"p\", null, \"I hope I was able to show that we can use the word component and function interchangeably when talking about React. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method takes a function as it's first argument, those are our custom \\\"user-defined\\\" components, like our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Hero\"), \" component. When React invokes that function, it passes along \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"props\"), \" as a single object. As we saw, JSX is just syntactic sugar for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"createElement\"), \" method:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"function Home() {\\n  return <Hero name=\\\"Dillon\\\" />\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-jsx\"\n  }), \"return React.createElement(Hero, { name: 'Dillon' })\\n\")), mdx(\"p\", null, \"The two snippets above are just two ways of writing the same thing.\"), mdx(\"br\", null), mdx(\"h2\", null, \"Resources\"), mdx(\"p\", null, \"With this understanding of React components as just functions we can apply principles of writing quality functions to writing quality react components. Here are some resources for learning those principles:\"), mdx(\"br\", null), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.entropywins.wtf/blog/2018/10/30/readable-functions-do-one-thing/\"\n  }), \"Readable Functions Do one Thing\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://eloquentjavascript.net/03_functions.html\"\n  }), \"Functions - Eloquent Javascript\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://dmitripavlutin.com/the-art-of-writing-small-and-plain-functions/\"\n  }), \"The art of writing plain and small functions\")));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"React Components are Just Functions","date":"December 16, 2020"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"id":"8394b154-b689-534b-9363-c527e09d8433","previous":{"id":"71ba6d38-f93e-538a-8f5c-9752654c2b47","fields":{"slug":"/the-cost-of-refactoring/"},"frontmatter":{"title":"The Cost of Refactoring"}},"next":null}}}