{"componentChunkName":"component---src-templates-generic-template-js","path":"/lectures/lecture5-react2","webpackCompilationHash":"041090671d318979d692","result":{"data":{"markdownRemark":{"htmlAst":{"type":"root","children":[{"type":"element","tagName":"h2","properties":{"id":"react-and-"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-and-","ariaLabel":"react and  permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"React and ..."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"react-and-proptypes"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-and-proptypes","ariaLabel":"react and proptypes permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"React and PropTypes"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"JavaScript is dynamically typed, and as such, it is easier to introduce\ntype-errors than in a statically typed language. To catch typing errors there\nare JavaScript extensions like "},{"type":"element","tagName":"a","properties":{"href":"https://www.typescriptlang.org/"},"children":[{"type":"text","value":"TypeScript"}]},{"type":"text","value":"\nand "},{"type":"element","tagName":"a","properties":{"href":"https://flowtype.org/"},"children":[{"type":"text","value":"Flow"}]},{"type":"text","value":" that provide static type checking. React\nprovides a form of dynamic type checking for props via\n"},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/typechecking-with-proptypes.html"},"children":[{"type":"text","value":"PropTypes"}]},{"type":"text","value":" that runs in development mode. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Each component as a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"propTypes"}]},{"type":"text","value":" object that specifies validators for the props.\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"PropTypes"}]},{"type":"text","value":" provides a wide range of potential validators. For example, for the\ncolor picker we could specify: "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"text","value":"LabeledSlider"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"propTypes "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  label"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" PropTypes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"string"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isRequired"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" PropTypes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"oneOfType"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    PropTypes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"string"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    PropTypes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isRequired"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  setValue"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" PropTypes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"func"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isRequired"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The more specific we can make these requirements the more likely we are to\ncatch type errors (generally true for all kinds of validation). Note that\nvalidation isn't the only purpose for providing "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"PropTypes"}]},{"type":"text","value":". Doing so is also a\nway of documenting the \"type signature\" of the component (analogous to a\nfunction signature in a statically typed language)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The need for "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"oneOfType"}]},{"type":"text","value":", and that the types could be inconsistent, is a \"code\nsmell\", that is an approach that doesn't seem quite right. The value is\nconceptually an integer, however the underlying value type of HTML input\nelements is specified to be a string (even if it is an input of type \"number\").\nInstead of allowing both, let's instead always convert the string to an\ninteger."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To do so, let's adopt a \"TDD-like\" approach in which we first update the\n\"test\", the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"PropTypes"}]},{"type":"text","value":", verify we have an error then fix that error. If we\nrequire "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"value"}]},{"type":"text","value":" to just be a number (i.e. "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"value: PropTypes.number.isRequired"}]},{"type":"text","value":"), we should see an error in the browser's\nJavaScript console like:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js:1446 Warning: Failed prop type: Invalid prop `value` of type `string` supplied to `LabeledSlider`, expected `number`.\n    in LabeledSlider (at App.js:52)\n    in ColorPicker (at App.js:81)\n    in App (at src/index.js:6)"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then we can update the slider "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"onChange"}]},{"type":"text","value":" callback to to parse the string into\nan integer:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"text","value":"onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"event"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setValue"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"parseInt"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"event"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"10"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now we should no longer observe a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"PropTypes"}]},{"type":"text","value":" error. To eliminate the chance\nfor obtaining fractional values from the slider I also explicitly set the step to be an\ninteger. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"react-and-css"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-and-css","ariaLabel":"react and css permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"React and CSS"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"How can we style our application?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"We can include a static CSS file as an asset, i.e. the traditional approach.\nBut this approach is not very modular and doesn't necessarily work well with\na component-based design as we would to have merge the styles for all\ncomponents."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We can \"import\" CSS files (using features of Webpack to bundle that CSS into\nthe JavaScript file) for each component. The challenge is that by default the\nimported CSS exports all class names into global selector scope creating a\npotential for naming collisions. We can either incorporate the \"scope\" into\nthe class naming (using different formal naming schemes) or use\n"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/webpack-contrib/css-loader#scope"},"children":[{"type":"text","value":"extensions"}]},{"type":"text","value":" to specify\nCSS classes as "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":":local"}]},{"type":"text","value":" and thus automatically create unique identifiers (the\nlatter, however, requires customizing our CSS for Webpack)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./ColorPicker.css'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Implement CSS-in-JS. CSS-in-JS integrates styling into the components as\nJavaScript code (similar to our previous example in which we created the\nstyles as JavaScript objects but with many more features, like handling\ndifferences in browsers). For example, using the "},{"type":"element","tagName":"a","properties":{"href":"https://www.styled-components.com"},"children":[{"type":"text","value":"styled\ncomponents"}]},{"type":"text","value":" library: "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm install --save styled-components"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We create a styled \"semantic\" component for the previous "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":".color-label"}]},{"type":"text","value":"\nclass"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" ColorLabel "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" styled"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\ndisplay: inline-block;\nwidth: 50px;\ntext-align: left;\n"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"and use it in place of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<div>"}]},{"type":"text","value":" in the JSX:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"ColorLabel"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"props"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","plain-text"]},"children":[{"type":"text","value":":"}]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"</"}]},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"ColorLabel"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Because these \"styles\" are just code, we can adapt the CSS based on props,\netc., e.g."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" ColorSwatch "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" styled"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\nwidth: 100px;\nheight: 100px;\nborder: 1px solid black;\nbackground: "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"props"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"rgb("}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"props"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"red"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":","}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"props"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"green"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":","}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"props"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"blue"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":";\n"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"and use the corresponding component:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"ColoSwatch"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"red"}]},{"type":"element","tagName":"span","properties":{"className":["token","script","language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","script-punctuation","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"red"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"green"}]},{"type":"element","tagName":"span","properties":{"className":["token","script","language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","script-punctuation","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"green"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"blue"}]},{"type":"element","tagName":"span","properties":{"className":["token","script","language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","script-punctuation","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"blue"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"/>"}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Note"}]},{"type":"text","value":" that in JSX, React components, including Style Components, need to\nstart with a "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/jsx-in-depth.html#specifying-the-react-element-type"},"children":[{"type":"text","value":"capital\nletter"}]},{"type":"text","value":".\nThat is how the JSX compiler distinguishes between HTML and React\ncomponents. I suggest defining your Styled Components outside of your React\ncomponents, e.g. before the class definition. If you create your Style\nComponent inside of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"render"}]},{"type":"text","value":" method, for instance, it appears that\nReact sees the component as entirely different in each re-render and so\nrebuilds that portion of the DOM. While the page will still look correct,\ninputs will lose focus (and potentially other undesirable behavior)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note that since we deleted the id attribute on the color swatch we will also need to update our tests (shown in the linked repository)."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The subtleties of CSS are left as an exercise for the reader, but much of the\ndebate about the best approach to CSS is a debate about "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"separation of\nconcerns"}]},{"type":"text","value":". "},{"type":"element","tagName":"a","properties":{"href":"https://en.wikipedia.org/wiki/Separation_of_concerns"},"children":[{"type":"text","value":"Separation of\nConcerns"}]},{"type":"text","value":" (SoC) will be a\nrecurring topic this semester, but in short, SoC is a design principle that\neach \"unit\" in a program should address a different and non-overlapping\nconcern."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this context, a common SoC argument around HTML/CSS is that HTML should\nspecify content (only) and CSS should specify the style (only), i.e. separate style from\ncontent. Proponents of CSS-in-JS also make a SoC argument, but that one\ncomponent should be entirely separate from the others."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h1","properties":{"id":"film-explorer-immutability-inheritance"},"children":[{"type":"element","tagName":"a","properties":{"href":"#film-explorer-immutability-inheritance","ariaLabel":"film explorer immutability inheritance permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Film Explorer, Immutability, Inheritance"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"exploring-the-film-explorer"},"children":[{"type":"element","tagName":"a","properties":{"href":"#exploring-the-film-explorer","ariaLabel":"exploring the film explorer permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Exploring the Film Explorer"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Experiment with a simple "},{"type":"element","tagName":"a","properties":{"href":"https://floating-island-22541.herokuapp.com/"},"children":[{"type":"text","value":"Film Explorer"}]},{"type":"text","value":" application and explore its "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/csci312-f19/example-filmexplorer-standalone"},"children":[{"type":"text","value":"code"}]},{"type":"text","value":". After implementing the "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/csci312-f19/example-react-color-picker"},"children":[{"type":"text","value":"Color Picker"}]},{"type":"text","value":" with PropTypes and Styled Components, the components of the Film Explorer should look familiar."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"key"}]},{"type":"text","value":" property in the \"list\" of films in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmTable"}]},{"type":"text","value":" (we saw this in our assignment as well). The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"key"}]},{"type":"text","value":" property uniquely identifies element in a list (to speedup rendering by identifying which specific elements have changed). From the "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/lists-and-keys.html"},"children":[{"type":"text","value":"React documentation"}]},{"type":"text","value":": \"A good rule of thumb is that elements inside the map() call need keys.\" "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"container-components"},"children":[{"type":"element","tagName":"a","properties":{"href":"#container-components","ariaLabel":"container components permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Container components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Exploring the demo, we observe that the films are sorted (and filterable) and can be \"clicked\" to show more detail (the poster and overview). We could so as part of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmTable"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":", but we would like to separate the logic and UI (recall \"Separation of Concerns\"). We can do so by introducing a \"container component\" (CC). A CC is not a thing per-se, it is a "},{"type":"element","tagName":"a","properties":{"href":"https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0"},"children":[{"type":"text","value":"design pattern"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A CC is concerned with \"how the application\" works and thus implements logic, is often stateful, but does not typically generate DOM (HTMl elements). Its counterpart is the \"presentation component\" (PC). A PC is focused on how the application looks and typically generates styled DOM but does not fetch or manipulate data. A CC will typically implement some logic, passing the result of that computation (pure or stateful) to children components (which may be PCs or more CCs) to be displayed."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For the Film Explorer we can extract two container components:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmTableComponent"}]},{"type":"text","value":": Implements the film sorting (and eventual filtering),\npassing the order films as a prop to the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmTable"}]},{"type":"text","value":" presentation component"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmComponent"}]},{"type":"text","value":": Implements the switching between summary and detail views"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"immutability"},"children":[{"type":"element","tagName":"a","properties":{"href":"#immutability","ariaLabel":"immutability permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Immutability"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Since React works by re-rendering on any state change, it is important for it to be aware that state has actually changed. The first piece of that is to only use our state setters. With primitive values, this is fairly robust. Consider the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmContainer"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"jsx"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-jsx"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"FilmContainer"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"props"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"showDetail"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setShowDetail"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" View "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" showDetail "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" MovieDetail "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" FilmSummary"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"View"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","spread"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"..."}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"text","value":"props"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"onClick"}]},{"type":"element","tagName":"span","properties":{"className":["token","script","language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","script-punctuation","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setShowDetail"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"showDetail"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"/>"}]}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We are storing a Boolean value, and when we request our variable we make it a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":", so we will get complaints from the interpreter if we try to write into it directly. The less obvious piece is what happens when we call the setter. React tries to be intelligent and not re-render if it doesn't have to, so it will check to see if the value is actually a new one. With a primitive value, this is just a simple equality check. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Things get more complex with objects, arrays, and other data structures (okay, they are all objects). These can be declared constant, but that only means that the "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"reference"}]},{"type":"text","value":" to the memory location stays constant. The stored value can be changed. This is legal:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" obj "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"a"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" b"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nobj"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"a "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This has a couple of problems. First, it means we can accidentally change state when React isn't looking. Second, even if we are careful and pass the modified object back to the setter, React will think nothing has changed because the reference is the same. It won't do a \"deep\" equality check, and even if it did, we just changed React's \"copy\" as well, because React just has a reference to the same object (it may not say \"pointer\" anywhere, but understanding how they work is important in all languages...). So what can we do?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmExplorer"}]},{"type":"text","value":" we have two examples. One approach is to be very cautious and "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"copy"}]},{"type":"text","value":" any object when we are going to make a change. Here is an example for when we set the rating of a film:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"filmid"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" rating"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" alteredFilms "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" films"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"film"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"film"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" filmid"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"film"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" rating "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" film"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setFilms"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"alteredFilms"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This actually provides two examples because we are changing two things: we are changing the rating of a single film, but the actual state variable is the whole list of films. If we just changed the film itself, we would be modifying state (the list "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"films"}]},{"type":"text","value":"), and that change would be invisible even if we passed "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"films"}]},{"type":"text","value":" to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setFilms()"}]},{"type":"text","value":" since the reference wouldn't have changed. So, you can see that we are using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"map()"}]},{"type":"text","value":", which generates a brand new array with the results of all of the individual function calls. Of course, our function merely returns the original items for all films except for the one we are changing. For the film itself, we use the spread operator to make a new object to replace the old copy. With care, this technique of making copies allows us to treat complex objects as if they were immutable."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Unsurprisingly, there are "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/markerikson/redux-ecosystem-links/blob/master/immutable-data.md"},"children":[{"type":"text","value":"a variety of libraries"}]},{"type":"text","value":" that provide you with actual immutable data structures that enforce the \"new copy on change\", all with different approaches and different mechanisms to make the process or or less transparent.  "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmExplorer"}]},{"type":"text","value":", we have added "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"immutable.js"}]},{"type":"text","value":", one of the older libraries for creating immutable data structures. In particular, we have wrapped the original array of films in an immutable "},{"type":"element","tagName":"a","properties":{"href":"https://immutable-js.github.io/immutable-js/docs/#/List"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"List"}]}]},{"type":"text","value":". This mostly works like an array, but it always returns a new copy when do something that would change it (like adding, removing, sorting, etc.). Unfortunately, while it "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"works"}]},{"type":"text","value":" like an array, it doesn't particularly "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"act"}]},{"type":"text","value":" like one. There are little changes like the fact that we need to use "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"size"}]},{"type":"text","value":" instead of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"length"}]},{"type":"text","value":", and other little quirks like that. We also have to be careful when swapping it in for an array to remember that "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sort"}]},{"type":"text","value":" on arrays sorts in place, while the immutable "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"List"}]},{"type":"text","value":" does not. This can have the effect of complicating the code, which is never a great sign."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In truth, if we wanted to be fully robust, there is an immutable "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Record"}]},{"type":"text","value":" as well, for standard objects, and we could have turned our "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"films"}]},{"type":"text","value":" state into a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"List"}]},{"type":"text","value":" of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Records"}]},{"type":"text","value":"..."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The big picture:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Don't mutate values you are using for state or props"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Primitive data types should be favored"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"To make state update "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"pure"}]},{"type":"text","value":", "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"replace"}]},{"type":"text","value":" instead of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"modify"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If performance becomes an issue, or you have deeply nested state objects, try using immutable data structures like those in immutable.js"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"composition-vs-inheritance-in-brief"},"children":[{"type":"element","tagName":"a","properties":{"href":"#composition-vs-inheritance-in-brief","ariaLabel":"composition vs inheritance in brief permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Composition vs. Inheritance (in brief)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In checking out "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":", we see it includes the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":" view plus\nthe additional image, description, etc. Thus we have an opportunity for code\nreuse. But how? Inheritance or Composition?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Both will work. But the community best practices are to use "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/composition-vs-inheritance.html"},"children":[{"type":"text","value":"composition\ninstead of\ninheritance"}]},{"type":"text","value":". That is\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":" uses but not does not inherit from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":". Why?  The\nformer, composition, is more flexible and can satisfy every potential use case\nfor inheritance."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"From our perspective there is value in following the community norms. Doing so\nimproves the readability and maintainability of our code. But it also not clear\nthat "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":" satisfies the principles of an inheritance relationship."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"More generally, how do we decide when to use inheritance? One is to ask if the\nrelationship is described by \"is a\" or \"has a\". The former suggests\ninheritance. For example a car \"is a\" vehicle but \"has\" wheels. In this\ncontext, the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":" \"has a\" "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":" but it is does not seem that\na "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":" \"is a\" "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":". "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A more formal way to think about inheritance is the "},{"type":"element","tagName":"a","properties":{"href":"https://en.wikipedia.org/wiki/Liskov_substitution_principle"},"children":[{"type":"text","value":"Liskov Subsitution\nPrinciple (LSP)"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Subtype Requirement: Let ϕ(x) be a property provable about objects "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" of type\n"},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"T"}]},{"type":"text","value":". Then ϕ(y) should be true for objects "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"y"}]},{"type":"text","value":" of type "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"S"}]},{"type":"text","value":" where "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"S"}]},{"type":"text","value":" is a\nsubtype of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"T"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Or alternately if "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"S"}]},{"type":"text","value":" is a subtype of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"T"}]},{"type":"text","value":", I should be able to use an "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"S"}]},{"type":"text","value":"\neverywhere I use a "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"T"}]},{"type":"text","value":". "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"LSP is one of "},{"type":"element","tagName":"a","properties":{"href":"https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)"},"children":[{"type":"text","value":"five key design\nprinciples"}]},{"type":"text","value":" for\nOO programming that we will discuss later in the course. LSP can help us\nidentify some problematic OO designs. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Consider squares and rectangles. A square \"is a\" rectangle. However, imagine we\ndefine a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setWidth"}]},{"type":"text","value":" method for our rectangle. We should reasonably believe that\nsetting the width of a rectangle will not change the height, but in a square we\nwould need to override "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setWidth"}]},{"type":"text","value":" to also change the height. Thus having\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Square"}]},{"type":"text","value":" inherit from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Rectangle"}]},{"type":"text","value":" would violate the LSP. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Would having "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":" inherit from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":" violate the LSP? Not\nentirely clear, but it would seem weird to think about using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmDetail"}]},{"type":"text","value":"\nwhere a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmSummary"}]},{"type":"text","value":" is expected."}]},{"type":"text","value":"\n"},{"type":"comment","value":" The Liskov Substitution Principle (LSP): https://dev.to/kayis/is-react-solid-630 "}],"data":{"quirksMode":false}},"frontmatter":{"path":"/lectures/lecture5-react2","title":"Lecture 5 - More React","name":"Lecture 5 - React2"},"parent":{"__typename":"File","id":"b8226b37-4eca-5992-a613-f09923318389","name":"lecture5-react2","modifiedTime":"Sep 27 2019 03:41"}}},"pageContext":{"isCreatedByStatefulCreatePages":false}}}