Summary
This post contains notes from chapter 4 in Fullstack React - "JSX and the Virtual DOM". The purpose of this chapter is to gain a better understanding of what is happening behind the scenes with React and to give us a lot of useful JSX tips and tricks.
Overview
This chapter takes a step back to give us a deeper understanding of what is happening when we are creating and rendering elements in React. It also goes over a lot of useful JSX tips and tricks.
Virtual DOM vs. Actual DOM
- In traditional javascript development, javascript code would change the page by directly manipulating the DOM. This is slow and it can be difficult to keep track of.
- React introduces the concept of a Virtual DOM.
- Virtual DOM is an in memory representation of the Actual DOM. It is basically a tree of javascript objects that mimic the actual COM.
- When a change is made to the Virtual DOM, React will update the entire Actual DOM. This sounds like it could be slow, but in reality it is very fast because:
- efficient diffing algorithms are used to only update what has changed
- updates can be made simultaneously across subtrees
- batch updates are made
React.createElement
- React.createElement(element, properties, children)
- Description: This method will create a new element, that can subsequently be inserted into the Virtual DOM and Actual Dom via the ReactDom.render() method
- Parameters:
- ReactElement - the html tag string for the element to render (I think this has to be an html tag, but maybe another type of ReacElement?)
- The element props - explained later in the book, so nothing to say here
- The children of the element we are creating - this can be simple text
ReactDom.render
- ReactDom.render(what, where, callback)
- Description: This method will add the "what" element into the Virtual and Actual DOM
- Parameters:
- what - the element that we want to mount
- where - the element that we are mounting to
- callback - an optional callback function that can be triggered after the element is rendered
JSX Tips and Tricks
JSX stands for JavaScript Syntax Extension, and it is a syntax React provides that looks a lot like HTML/XML. Rather than building our component trees using normal JavaScript directly, we write our components almost as if we were writing HTML. Under the covers, JSX is just making a bunch of React.createElement statements.
JSX provides the following 4 concepts to make using JSX easy:
Attribute expressions
In JSX, we use curly braces { } to denote javascript instead of quotes ""
Conditional Child expressions
Conditional child expressions is a common pattern where we will render a child element based on some boolean expression.
We can also use a ternary operator to conditionally render an element.
Another common pattern is to create a function to toggle the element that should be rendered:
INSERT SAMPLE CODE HERE
Boolean attributes
It standard HTML, some attributes will be applied just by the name of the attribute being present. For example, the disabled attribute essentially applies an attributed disabled="true". In JSX, we have to apply the entire syntax and can't just take a shortcut.
Comments
Comments in JSX are denoted by {/* */}
JSX Spread Syntax
Sometimes when we can have many props to pass to a component and it can be cumbersome to list each one individually. JSX makes available the spread operator so we can apply all properties of an object to an element.
class vs className
We can't use Javascript's reserved words in our JSX syntax, so when we are setting a css class, we have to use className instead of class.
Applying multiple classes trick
You can apply multiple classes by putting those classes in an array and then use string.join to add them to the element.
classnames npm package
classnames is a useful npm package that will let you take the properties of an object and apply the names of those properties to an element if those properties evaluate to true in the object.
for vs htmlFor
Similar to class vs className, we can't use for because it is a reserverd word. Instead we have to use htmlFor.
data-anything
If we want to apply custom attributes to native HTML elements, we can prefix the attribute with data-. This is only necessary on native HTML elements, custom components can have attributes named to anything.
aria-anything
We can apply web accessibility attributes by prefixing the attribute with aria-
Attribute expressions
In JSX, we use curly braces { } to denote javascript instead of quotes ""
1 2 3 4 5 6 7 8 9 10 11 | class JSXExample extends React.Component { render () { const title = 'The Jerk'; return ( <div>The title is {title}</div> ); } } ReactDOM.render(<JSXExample />, document.getElementById('content')); |
Conditional Child expressions
Conditional child expressions is a common pattern where we will render a child element based on some boolean expression.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | class JSXExample extends React.Component { renderMovie2 = () => { return ( <Movie2 /> ); }; render () { const showMovie = 'Movie2'; return ( <div> <Movie1 /> {showMovie === 'Movie2' && this.renderMovie2()} </div> ); } } class Movie1 extends React.Component { render () { return ( <div>The Jerk</div> ); } } class Movie2 extends React.Component { render () { return ( <div>Forest Gump</div> ); } } ReactDOM.render(<JSXExample />, document.getElementById('content')); |
We can also use a ternary operator to conditionally render an element.
1 2 3 4 5 6 7 8 9 10 11 | class JSXExample extends React.Component { render () { const showMovie = 'Movie2'; return ( <div> {showMovie === 'Movie1' ? <Movie1 /> : <Movie2 />} </div> ); } } |
Another common pattern is to create a function to toggle the element that should be rendered:
INSERT SAMPLE CODE HERE
Boolean attributes
It standard HTML, some attributes will be applied just by the name of the attribute being present. For example, the disabled attribute essentially applies an attributed disabled="true". In JSX, we have to apply the entire syntax and can't just take a shortcut.
1 2 3 4 5 6 7 8 9 10 11 | class JSXExample extends React.Component { render () { const formDisabled = true; return ( <div> <input name='Name' disabled={formDisabled} /> </div> ); } } |
Comments
Comments in JSX are denoted by {/* */}
1 2 3 4 5 6 7 8 9 10 11 12 | class JSXExample extends React.Component { render () { const formDisabled = true; return ( <div> {/* This is a comment */} This text will appear </div> ); } } |
JSX Spread Syntax
Sometimes when we can have many props to pass to a component and it can be cumbersome to list each one individually. JSX makes available the spread operator so we can apply all properties of an object to an element.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class JSXExample extends React.Component { render () { const movie = { title: 'The Jerk', director: 'Carl Reiner' }; return ( <div> <Movie {...movie} /> </div> ); } } class Movie extends React.Component { render () { return ( <div>{this.props.title} by {this.props.director}</div> ); } } ReactDOM.render(<JSXExample />, document.getElementById('content')); |
class vs className
We can't use Javascript's reserved words in our JSX syntax, so when we are setting a css class, we have to use className instead of class.
1 2 3 4 5 6 7 8 9 | class JSXExample extends React.Component { render () { return ( <div className='blueBackground'> The Jerk </div> ); } } |
Applying multiple classes trick
You can apply multiple classes by putting those classes in an array and then use string.join to add them to the element.
1 2 3 4 5 6 7 8 9 10 11 | class JSXExample extends React.Component { render () { const cssClasses = [ 'blueBackground', 'redText' ]; return ( <div className={cssClasses.join(' ')}> The Jerk </div> ); } } |
classnames npm package
classnames is a useful npm package that will let you take the properties of an object and apply the names of those properties to an element if those properties evaluate to true in the object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class JSXExample extends React.Component { render () { const cssClasses = classNames({ blueBackground: true, redText: false }); return ( <div className={cssClasses}> The Jerk </div> ); } } |
for vs htmlFor
Similar to class vs className, we can't use for because it is a reserverd word. Instead we have to use htmlFor.
1 2 3 4 5 6 7 8 9 10 | class JSXExample extends React.Component { render () { return ( <div> <label htmlFor='title'>Title:</label> <input type='text' name='title' /> </div> ); } } |
data-anything
If we want to apply custom attributes to native HTML elements, we can prefix the attribute with data-. This is only necessary on native HTML elements, custom components can have attributes named to anything.
1 2 3 4 5 6 7 8 9 | class JSXExample extends React.Component { render () { return ( <div data-director='Carl Reiner'> The Jerk </div> ); } } |
aria-anything
We can apply web accessibility attributes by prefixing the attribute with aria-
1 2 3 4 5 6 7 8 9 | class JSXExample extends React.Component { render () { return ( <div aria-hidden={true}> The Jerk </div> ); } } |
No comments:
Post a Comment