{"componentChunkName":"component---src-templates-generic-template-js","path":"/lectures/lecture4-react","webpackCompilationHash":"041090671d318979d692","result":{"data":{"markdownRemark":{"htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"React is a framework for just the View in MVC (although not all would agree with that characterization). And in particular it is designed to solve a very specific problem in client side applications: implementing updates to multiple views of the same data. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Consider the Color Picker... for each color component, the state, we have three \"views\": 1) the position of the slider itself, 2) the numeric value label, and 3) the color swatch. All three need to be updated when we change that component. How can we do so? What patterns could be relevant?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Event-based model (e.g. Backbone): Changing the data triggers an event. Views can register for those events and update themselves when notified."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Two-way binding (.e.g Angular): Assigning to a value propagates the data to dependent components and components, e.g. an input, can make updates that \"flow back\"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Efficient re-rendering (e.g. React): React takes a simpler approach... just re-render all of the components when the data changes. "}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A key innovation in React is making that re-rendering process very "},{"type":"element","tagName":"a","properties":{"href":"https://calendar.perfplanet.com/2013/diff/"},"children":[{"type":"text","value":"fast"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"React maintains a virtual DOM that represents the ideal state of the UI. Changing the application state triggers re-rendering, which changes the virtual DOM (those changes are fast since only the \"virtual\" DOM is changing). Any differences between the virtual DOM and actual DOM are then reconciled to the bring the actual DOM to the desired state. But only those elements that changed are updated making this process more efficient."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Those operations on the (virtual) DOM are the \"part that is the same\" and occur entirely \"behind the scenes\" within React. As a developer your focus is just on rendering the desired UI."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"if-react-is-just-the-v-what-about-m--c"},"children":[{"type":"element","tagName":"a","properties":{"href":"#if-react-is-just-the-v-what-about-m--c","ariaLabel":"if react is just the v what about m  c 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":"If React is just the V, what about M & C?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As we will see React components can be quite sophisticated and incorporate features we might otherwise associate with models and controllers. Related tools like Flux or Redux are sometimes used with React in those roles. Or React is often used for the client side of an application whose server has M & C-like functionality."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"create-react-app"},"children":[{"type":"element","tagName":"a","properties":{"href":"#create-react-app","ariaLabel":"create react app 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":"create-react-app"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Just as we implemented packages from the top-down, i.e. starting with a\nskeleton, we will build React applications from the top-down using the\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"create-react-app"}]},{"type":"text","value":" (CRA) skeleton tool.\n"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/facebook/create-react-app"},"children":[{"type":"text","value":"CRA"}]},{"type":"text","value":" sets up a fully functional\nReact application with all the necessary supporting infrastructure (e.g.\nWebpack for packaging production assets and Babel for transpiling). CRA is not\nthe only way to setup a React application, and as with some of our other tools,\ne.g. the AirBnB ESLint configuration, we may not agree with some of the choices\nmade by the CRA developers. However, it provides a robust starting point with many best practices built in."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"More generally, we often want to seek out a skeleton when starting a project\n(not just with React) to get up and going quickly (and hopefully with best\npractices). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Getting started with CRA:"}]},{"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":"npx create-react-app my-app\ncd my-app\nnpm start"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The above command sequence creates the application and starts a development\nserver with your application at "},{"type":"element","tagName":"a","properties":{"href":"http://localhost:3000"},"children":[{"type":"text","value":"http://localhost:3000"}]},{"type":"text","value":". You can also run your\ntests via "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm test"}]},{"type":"text","value":" and create an optimized bundle for deployment via "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm run build"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Over the course of the semester we will learn about some of the nice features\nof this skeleton. Your assignment skeletons have all been created with CRA."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"react-basic-concepts"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-basic-concepts","ariaLabel":"react basic concepts 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: basic concepts"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"components"},"children":[{"type":"element","tagName":"a","properties":{"href":"#components","ariaLabel":"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":"Components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The fundamental unit of React is the component. In React, we can implement components as either "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"classes"}]},{"type":"text","value":" or "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"functions"}]},{"type":"text","value":". For our purposes, we will primarily stick to function-based components, but many examples you find online will use classes."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A function-based component is a function that takes a single argument, which we refer to as the "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"props"}]},{"type":"text","value":", and returns a hierarchy of components (think of these children components like a nested tree, similar to the DOM itself) with a single root. The root element returned by the function is what is added to the virtual DOM. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first step in building a React app is break down the UI (the view) into a hierarchy of components and sub-components. In the color picker there is one main component (the color picker itself, with the swatch) and the 3 sliders and corresponding value displays. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"state"},"children":[{"type":"element","tagName":"a","properties":{"href":"#state","ariaLabel":"state 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":"State"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"What state do we need? The value of the sliders. We know from our earlier implementation that the input element itself can hold state. However in React, the typical practice is to use "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"controlled"}]},{"type":"text","value":" components, in which the value of an input is controlled by state in the React component. This enables us to use that state to control other aspects of the view while maintaining a \"single source of truth\"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To add state information to a function component, we will use "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/hooks-intro.html"},"children":[{"type":"text","value":"hooks"}]},{"type":"text","value":", which is a brand new addition. At its simplest, we can create state with the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"useState()"}]},{"type":"text","value":" function. This returns an array with a constant value (the current value for our state object, initialized to the value we pass into "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"useState()"}]},{"type":"text","value":") and a setter function for updating the state. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Some notes about state:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Do not modify state directly, instead use the setter."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Favor immutable state data (like ints) so you aren't tempted to change the contents."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"State updates may be asynchronous. React may batch updates, and so you\nshouldn't assume the state has actually changed after the call to the setter."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"State updates are merged: React merges the object you provide into the\ncurrent state so you can update a single property at a time."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"But that puts us in the same place as before in the non-React color picker. We need to make the values of each color component available to the parent to control the color of swatch. Per the React "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/lifting-state-up.html"},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Often, several components need to reflect the same changing data. We\nrecommend lifting the shared state up to their closest common ancestor."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We will pull the state for the color values up to the parent component and pass those values back down as props to the individual sliders. But, all React components must act like pure functions with respect to their props. That is a component can't modify its props (this enables efficient updates). Or alternately, think of it as \"data flows down\" via the props. To communicate updates \"back up\" we supply a callback to the child that modifies the state in the parent. Using this approach we preserve the data flow invariants expected by React."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"With this change the sliders don't need to know what color they are. All the state is encapsulated in the parent component and passed in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"props"}]},{"type":"text","value":". "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"pure-components"},"children":[{"type":"element","tagName":"a","properties":{"href":"#pure-components","ariaLabel":"pure 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":"Pure Components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Since the slider doesn't have any state, it is now considered a \"pure component\" (and it should be a pure function, i.e. the output is a function only of the inputs with no side effects). React can optimize these considerably, most particularly, it can avoid re-rendering them if the props haven't changed -- even if the parent has re-rendered."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"example"},"children":[{"type":"element","tagName":"a","properties":{"href":"#example","ariaLabel":"example 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":"Example"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In class we started the React version of the color picker. The repository containing that code can be found on "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/csci312-f19/example-react-color-picker"},"children":[{"type":"text","value":"GitHub"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"react-and-jsx"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-and-jsx","ariaLabel":"react and jsx 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 JSX"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Since rendering is tightly coupled with other UI logic in React, React provides\nJSX, a syntax extension to JavaScript, for describing the elements in the UI.\nThese elements can be simple HTML:"}]},{"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":" heading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"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":"text","value":"h1"}]},{"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":"Hello, world!"}]},{"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":"text","value":"h1"}]},{"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":"or React components:"}]},{"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":" person "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"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":"Person"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"name"}]},{"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":"p"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name"},{"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":"address"}]},{"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":"p"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"addr"},{"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":"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 curly braces specify embedded JavaScript. The attributes becomes the props object for the component. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Since JSX is an extension to JavaScript, we will need a compiler to convert it to standard JavaScript. That is the JSX is being translated to the API we saw previously. CRA integrates the Babel compiler to transpile JSX (and support features of ES6). We will use JSX in our components (as it is much more concise and clear). However, you should realize that it is being translated into normal JavaScript functions. Try out the above examples in the "},{"type":"element","tagName":"a","properties":{"href":"https://babeljs.io/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=PTAEFEA8EMFsAcA2BTUAJAKgWQDICgBjAewDsBnAF1AAtloATASxIHNQBeUAHmoEYA-NMkSIiAGlAB3IgCdE9AIRdgffgG48ICDAQpQxBKWQkKhUpVDxkMsqQ7cACtdslQJOMnYBveADp3sMgAvqAM9DLIZGTefmEyIcDqQA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=es2015%2Creact%2Cstage-2&prettier=false&targets=&version=7.2.2"},"children":[{"type":"text","value":"Babel repl"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"controlled-vs-uncontrolled-components"},"children":[{"type":"element","tagName":"a","properties":{"href":"#controlled-vs-uncontrolled-components","ariaLabel":"controlled vs uncontrolled 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":"Controlled vs. uncontrolled components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In creating the color picker, we described the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<input>"}]},{"type":"text","value":" elements as \"controlled\". Controlled components are form elements with state controlled by React. Uncontrolled components maintain their own state. The latter is the way "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<input>"}]},{"type":"text","value":" elements naturally work (recall our original color picker)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The former, \"controlled\", is the "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/forms.html#controlled-components"},"children":[{"type":"text","value":"recommended approach"}]},{"type":"text","value":" as it ensures there is only one source of truth, the React state. We set the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<input>"}]},{"type":"text","value":" element's value from state, and provide an "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"onChange"}]},{"type":"text","value":" (or other relevant) handler to update that state in response to user input. Each state change triggers a re-rendering that shows the changes the user just initiated. The React "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/forms.html#controlled-components"},"children":[{"type":"text","value":"forms documentation"}]},{"type":"text","value":" has a number of examples of controlled inputs, e.g. for a text input:"}]},{"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":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setTitle"},{"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","string"]},"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\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":"text","value":"input"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"type"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"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":"text","value":"text"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"value"}]},{"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":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"onChange"}]},{"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","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":"setTitle"}]},{"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":"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":"The value of the component is set from the parent's state and any changes are immediately captured and used to update the parent's state. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"react-in-summary"},"children":[{"type":"element","tagName":"a","properties":{"href":"#react-in-summary","ariaLabel":"react in summary 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 in summary"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"React implements the View in MVC"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"A React applications is organized as components"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"A component takes in parameters, the \"props\", and returns a hierarchy of\nviews to display"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"These hierarchy of views update the virtual DOM. Changes to the virtual DOM are efficiently propagated to the actual DOM in the reconciliation process."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"There (generally) must be a single root object (version 16 added\n"},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/fragments.html"},"children":[{"type":"text","value":"fragments"}]},{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Components can't change their props (and parents can't see their children's state). Information is passed to parents via callbacks (passed in the props)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"A React element might be simple HTML, e.g. a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<div>"}]},{"type":"text","value":" or a React component"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Components can be classes, or functions that return views. We will use the latter."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As you are starting to work with React, I recommend the "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/thinking-in-react.html"},"children":[{"type":"text","value":"\"Thinking in React\""}]},{"type":"text","value":" section of the React documentation."}]}],"data":{"quirksMode":false}},"frontmatter":{"path":"/lectures/lecture4-react","title":"Lecture 4 - Introduction to React","name":"Lecture 4 - React"},"parent":{"__typename":"File","id":"4d9179b5-afe8-58bd-b9d4-b07cd166c841","name":"lecture4-react","modifiedTime":"Oct 9 2019 13:01"}}},"pageContext":{"isCreatedByStatefulCreatePages":false}}}