{"id":173,"date":"2018-02-23T16:35:06","date_gmt":"2018-02-23T16:35:06","guid":{"rendered":"https:\/\/jmrowe.com\/blog\/?p=173"},"modified":"2018-08-31T20:24:22","modified_gmt":"2018-08-31T20:24:22","slug":"notes-for-udemy-course-the-complete-react-web-developer-course-with-redux","status":"publish","type":"post","link":"https:\/\/jmrowe.com\/blog\/notes-for-udemy-course-the-complete-react-web-developer-course-with-redux\/","title":{"rendered":"Notes for Udemy Course &#8220;The Complete React Web Developer Course (with Redux)&#8221;"},"content":{"rendered":"<p>Notes for Udemy Course &#8220;The Complete React Web Developer Course (with Redux)&#8221; &#8211; https:\/\/www.udemy.com\/react-2nd-edition\/<\/p>\n<p>React uses jsx and ES6 which means it requires Babel ( requires node ). Two scripts are required to work with React in the browser. React and ReactDOM. Below is a sample React component that has\u00a0 toggle visibility functionality.<\/p>\n<pre class=\"lang:js decode:true \">import React from 'react';\r\nimport { render } from 'react-dom';\r\n\/\/ required to work with React in the browser\r\n\r\n\/\/ Any component must extend React.Component and have at the very least a \r\n\/\/ render() method.\r\n\r\nclass VisibilityComponent extends React.Component {\r\n\/\/ constructor for component really only needs to use super(props) instead of super() \r\n\/\/ if you need to reference the props in the constructor\r\n\r\n  constructor(props) {\r\n    super(props);\r\n    \/\/ We bind all methods so that it references the correct this instance.   \r\n    this.setVisibility = this.setVisibility.bind(this);\r\n    \/\/ set the initial state variables\r\n    this.state = {\r\n      visibility: false\r\n    };\r\n\r\n  }\r\n  \/\/ method that toggles the visibility state variable.\r\n  setVisibility() {\r\n  \/\/ updating setState should be a function that returns a new object.\r\n  \/\/ if the previous state's value is needed, add prevState ( can be named anything )\r\n  \/\/ to the this.setState method's parameter.\r\n    this.setState((prevState) =&gt; {\r\n      return { visibility: !prevState.visibility }\r\n    }\r\n    );\r\n  }\r\n  \/\/ return jsx that can be inclosed by ( ) \r\n  render() {\r\n    return (\r\n      &lt;div&gt;\r\n        &lt;button onClick={this.setVisibility}&gt;Toggle visibility&lt;\/button&gt;\r\n         \/\/ if statement checking visibility state value \r\n         \/\/ shows 'it is shown' if true, 'not shown' if it is false.\r\n        {this.state.visibility ? 'it is shown' : 'not shown'}\r\n      &lt;\/div&gt;\r\n\r\n    )\r\n\r\n  }\r\n\r\n}\r\n\r\n\/\/ finally, use render function from ReactDOM to attach the app to the DOM.\r\nrender(&lt;VisibilityComponent \/&gt;, document.getElementById('root'));\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>If components are nested, data as props can only be sent down &#8211; not up. So, on the parent component a method can be passed to the child component as a prop in order to send the information back to the parent.<\/p>\n<p><strong>Stateless functional components<\/strong><\/p>\n<p>Another type of component\u00a0 that can be reduced to a single function call because they do not have any state to handle of their own.\u00a0Mostly used for &#8220;presentation&#8221; type components. They can use props but aren&#8217;t accessible through *this* .<\/p>\n<p>This type of component is &#8220;faster&#8221; as it has less overhead as it doesn&#8217;t handle state.<\/p>\n<pre class=\"lang:js decode:true\">\/\/ Stateless functional component example\r\n\/\/ The name of the variable will be the component name\r\n\/\/ i.e. &lt;User \/&gt;\r\n\r\nconst User = (props) =&gt; {\r\n\/\/ like regular components, it has a render method but it is\r\n\/\/ just the body of the function itself\r\n\r\nreturn (\r\n  &lt;div&gt; Any valid JSX will work here {props.name} &lt;\/div&gt;\r\n);\r\n};\r\n\r\n\/\/ Can setup defaults for props using below:\r\nUser.defaultProps({\r\nname=\"default name if not given one\"\r\n});\r\n\r\nReactDOM.render(&lt;User name=\"Jason Rowe\"\/&gt;,document.getElementById('root');<\/pre>\n<p>Small tricks for conditional rendering<\/p>\n<pre class=\"lang:js decode:true\">\/\/ Below will only show the h2 tags if the title is not empty\r\n{this.props.title &amp;&amp; &lt;h2&gt;{this.props.title}&lt;\/h2&gt;}<\/pre>\n<p>For the arrow function, if you are return just an object you can use the following syntax:<\/p>\n<pre class=\"lang:js decode:true\">this.setState(() =&gt; ({ options:[] }));\r\n\r\n\/\/ key difference is that following the arrow it must include () so \r\n\/\/ it knows it is an object rather then the normal opening and\r\n\/\/ closing brackets of the arrow function\r\n<\/pre>\n<p>In React, methods to update a parent component are passed down to child components via props.<\/p>\n<p><strong>Lifecycle methods<\/strong><\/p>\n<p>Methods are available to hook in to when a class based component is added\/removed\/updated in React. Common ones to use are componentDidMount() for fetching initial data, and componentDidUpdate(prevProps, prevState) for saving updated changes back to the db.<\/p>\n<p>When using componentDidUpdate, make sure the prevState and current state are not equal ( !==) so that a save to db\/localStorage is not called that is not needed.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Localstorage Notes<\/strong><\/p>\n<pre class=\"lang:default decode:true\">\/\/ valid commands\r\nlocalStorage.setItem('name', 'Jason');\r\n\r\nlocalStorage.getItem('name');\r\n\r\nlocalStorage.removeItem('name');\r\n\r\n\/\/ localStorage can only store strings. Will automatically convert \r\n\/\/ a number i.e. 26 to \"26\" . To make best use, we use JSON methods\r\n\r\n\/\/ below will turn a javascript object to a string that\r\n\/\/ we can store in localStorage\r\nJSON.stringify(Object); \r\n\r\n\/\/ below will turn a string back to a javascript object\r\nJSON.parse(String);<\/pre>\n<p>When within a method that was attached to a onClick event ( or any other similar method ), you can reference the field\/value by the following type of example:<\/p>\n<pre class=\"lang:js decode:true\">&lt;form onSubmit={this.handleAddOption}&gt;\r\n &lt;input type=\"text\" name=\"option\" \/&gt;\r\n &lt;button&gt; Add option &lt;\/button&gt;\r\n&lt;\/form&gt;\r\n\r\n\/\/ Within handleAddOption(e) can use the following to reference the \r\n\/\/ input field's value. It uses the name field for what you would reference.\r\n\/\/ in the case, name=\"option\"\r\n\r\ne.target.elements.option.value;<\/pre>\n<p><strong>Children props ( slots )<\/strong><\/p>\n<p>Dynamic content that be added between a components tag can be added to be placed within the layout of the components it&#8217;s self. For example:<\/p>\n<pre class=\"lang:default decode:true \">const Layout = (props) =&gt; return (\r\n  &lt;div&gt;\r\n   &lt;h1&gt; Random Header &lt;\/h1&gt;\r\n   {props.children} \r\n   \/\/ above will add what was put between the &lt;Layout&gt; &lt;\/Layout&gt; tag\r\n  &lt;\/div&gt;\r\n);\r\n\r\nReactDOM.render(&lt;Layout&gt;&lt;p&gt; This content will be added as a child prop &lt;\/p&gt;&lt;\/Layout&gt;, document.getElementById('root');\r\n\r\n\/\/ The &lt;p&gt; &lt;\/p&gt; content will be added within the Layout component<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Simple form value\/onChange practice:<\/strong><\/p>\n<p>Can create a single handleChange method to handle all form values and updates that are used in state.<\/p>\n<pre class=\"lang:default decode:true\">handleChange = event =&gt; {\r\n   \/\/uses a object deconstructor to create name \/ value variables from\r\n   \/\/ the even.target object\r\n\r\n    const {name, value} = event.target;\r\n\r\n    this.setState({\r\n        [name] : value\r\n    });\r\n}<\/pre>\n<p>Now we can use same method for all form fields:<\/p>\n<pre class=\"lang:default decode:true \">render() {\r\n    const { name, job } = this.state; \r\n\r\n    return (\r\n        &lt;form&gt;\r\n            &lt;label&gt;Name&lt;\/label&gt;\r\n            &lt;input \r\n                type=\"text\" \r\n                name=\"name\" \r\n                value={name} \r\n                onChange={this.handleChange} \/&gt;\r\n            &lt;label&gt;Job&lt;\/label&gt;\r\n            &lt;input \r\n                type=\"text\" \r\n                name=\"job\" \r\n                value={job} \r\n                onChange={this.handleChange}\/&gt;\r\n        &lt;\/form&gt;\r\n    );\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Misc React Notes<\/strong><\/p>\n<p>In JSX, all normal html attributes such as onclick and onchange MUST be camel case.. i.e.e onClick and onChange<\/p>\n<p>All components must start with a capital letter.<\/p>\n<p>JSX conditional rendering :<\/p>\n<p>ternary operator is accepted i.e. true ? &#8216;show this if true&#8217; : &#8216; value if false&#8217;<\/p>\n<p>if\/else can not be used in {} jsx since it is a statement and not an expression.<\/p>\n<p>&amp;&amp; AND Operator<\/p>\n<pre class=\"lang:default decode:true \">{user.age&gt;18 &amp;&amp; &lt;p&gt;{user.age}&lt;\/p&gt;}\r\n\r\n\/\/ If the first value is true (user.age is greater than 18)\r\n\/\/ then the second value is returned.\r\n\/\/ This is useful to only show something if a certain value is true.\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Notes for Udemy Course &#8220;The Complete React Web Developer Course (with Redux)&#8221; &#8211; https:\/\/www.udemy.com\/react-2nd-edition\/ React uses jsx and ES6 which means it requires Babel ( requires node ). Two scripts are required to work with React in the browser. React and ReactDOM. Below is a sample React component that has\u00a0 toggle visibility functionality. import React [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-173","post","type-post","status-publish","format-standard","hentry","category-javascript"],"_links":{"self":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/comments?post=173"}],"version-history":[{"count":28,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/173\/revisions"}],"predecessor-version":[{"id":250,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/173\/revisions\/250"}],"wp:attachment":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/media?parent=173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/categories?post=173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/tags?post=173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}