4,452
edits
add personal blogs to references |
|||
(12 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Notes from Learning React, 2nd Edition by Porcello & Banks | Notes from '''Learning React, 2nd Edition''' by Porcello & Banks and other sources | ||
= Installation = | = Installation = | ||
Line 86: | Line 86: | ||
== Arrow functions and scope == | == Arrow functions and scope == | ||
Reference | |||
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions Arrow functions] | |||
* [https://www.codementor.io/dariogarciamoya/understanding-this-in-javascript-with-arrow-functions-gcpjwfyuc Understanding "this" in javascript with arrow functions] | |||
<source lang="js"> | <source lang="js"> | ||
Line 116: | Line 123: | ||
tahoe.print(); // Freel, Rose, Tallac, Rubicon, Silver | tahoe.print(); // Freel, Rose, Tallac, Rubicon, Silver | ||
</source> | </source> | ||
== Destructing objects == | == Destructing objects == | ||
Line 259: | Line 265: | ||
== Spread operator == | == Spread operator == | ||
Reference: [https://github.com/tc39/proposal-object-rest-spread Object Rest/Spread Properties for ECMAScript] | |||
<source lang="js"> | <source lang="js"> | ||
Line 327: | Line 335: | ||
// } | // } | ||
</source> | </source> | ||
== Asynchronous requests == | == Asynchronous requests == | ||
Line 1,474: | Line 1,481: | ||
= React with JSX = | = React with JSX = | ||
== React elements as JSX == | |||
=== Nested components === | |||
<source lang="html"> | |||
<IngredientsList> | |||
<Ingredient /> | |||
<Ingredient /> | |||
<Ingredient /> | |||
</IngredientsList> | |||
</source> | |||
=== ClassName === | |||
Since <code>class</code> is a reserved word in JavaScript, className is used to define the class attribute. | |||
=== JavaScript Expressions === | |||
<source lang="js"> | |||
<h1>{title}</h1> | |||
<input type="checkbox" defaultChecked="{false}" /> | |||
</source> | |||
=== Evaluation === | |||
<source lang="js"> | |||
<h1>{"Hello" + title}</h1> | |||
<h1>{title.toLowerCase().replace}</h1> | |||
function appendTitle({ title }) { | |||
console.log(`${title} is great!`); | |||
} | |||
</source> | |||
=== Mapping Arrays with JSX === | |||
<source lang="js"> | |||
<ul> | |||
{props.ingredients.map((ingredient, i) => ( | |||
<li key="{i}">{ingredient}</li> | |||
))} | |||
</ul> | |||
</source> | |||
== Babel == | |||
template file to use | |||
<source lang="html"> | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<meta charset="utf-8" /> | |||
<title>React Examples</title> | |||
</head> | |||
<body> | |||
<div id="root"></div> | |||
<!-- React Library & React DOM --> | |||
<script src="https://unpkg.com/react@16.8.6/umd/react.development.js"></script> | |||
<script src="https://unpkg.com/react-dom@16.8.6/umd/react-dom.development.js"></script> | |||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | |||
<script type="text/babel"> | |||
// JSX code here. Or link to separate JavaScript file that contains JSX. | |||
</script> | |||
</body> | |||
</html> | |||
</source> | |||
== Recipes as JSX == | |||
<source lang="js"> | |||
const data = [ | |||
{ | |||
name: "Baked Salmon", | |||
ingredients: [ | |||
{ name: "Salmon", amount: 1, measurement: "l lb" }, | |||
{ name: "Pine Nuts", amount: 1, measurement: "cup" }, | |||
{ name: "Butter Lettuce", amount: 2, measurement: "cups" }, | |||
{ name: "Yellow Squash", amount: 1, measurement: "med" }, | |||
{ name: "Olive Oil", amount: 0.5, measurement: "cup" }, | |||
{ name: "Garlic", amount: 3, measurement: "cloves" } | |||
], | |||
steps: [ | |||
"Preheat the oven to 350 degrees.", | |||
"Spread the olive oil around a glass baking dish.", | |||
"Add the yellow squash and place in the oven for 30 mins.", | |||
"Add the salmon, garlic, and pine nuts to the dish.", | |||
"Bake for 15 minutes.", | |||
"Remove from oven. Add the lettuce and serve." | |||
] | |||
}, | |||
{ | |||
name: "Fish Tacos", | |||
ingredients: [ | |||
{ name: "Whitefish", amount: 1, measurement: "l lb" }, | |||
{ name: "Cheese", amount: 1, measurement: "cup" }, | |||
{ name: "Iceberg Lettuce", amount: 2, measurement: "cups" }, | |||
{ name: "Tomatoes", amount: 2, measurement: "large" }, | |||
{ name: "Tortillas", amount: 3, measurement: "med" } | |||
], | |||
steps: [ | |||
"Cook the fish on the grill until cooked through.", | |||
"Place the fish on the 3 tortillas.", | |||
"Top them with lettuce, tomatoes, and cheese." | |||
] | |||
} | |||
]; | |||
// A function component for an individual Recipe | |||
function Recipe (props) { | |||
... | |||
} | |||
// A function component for the Menu of Recipes | |||
function Menu (props) { | |||
return ( | |||
<article> | |||
<header> | |||
<h1>{props.title}</h1> | |||
</header> | |||
<div className="recipes"> | |||
{props.recipes.map((recipe, i) => ( | |||
<Recipe | |||
key={i} | |||
name={recipe.name} | |||
ingredients={recipe.ingredients} | |||
steps={recipe.steps} | |||
/> | |||
))} | |||
// equivalent to | |||
{ | |||
props.recipes.map((recipe, i) => <Recipe key={i} {...recipe} />); | |||
} | |||
</div> | |||
</article> | |||
); | |||
} | |||
// A call to ReactDOM.render to render our Menu into the current DOM | |||
ReactDOM.render( | |||
<Menu recipes={data} title="Delicious Recipes" />, | |||
document.getElementById("root") | |||
); | |||
</source> | |||
we can access title & recipes vars directly, so vars don't have to be prefixed with props: | |||
<source lang="js"> | |||
function Menu({ title, recipes }) { | |||
return ( | |||
<article> | |||
<header> | |||
<h1>{title}</h1> | |||
</header> | |||
<div className="recipes"> | |||
{recipes.map((recipe, i) => ( | |||
<Recipe key={i} {...recipe} /> | |||
))} | |||
</div> | |||
</article> | |||
); | |||
} | |||
</source> | |||
code for the component for each individual recipe: | |||
<source lang="js"> | |||
function Recipe({ name, ingredients, steps }) { | |||
return ( | |||
<section id={name.toLowerCase().replace(/ /g, "-")}> | |||
<h1>{name}</h1> | |||
<ul className="ingredients"> | |||
{ingredients.map((ingredient, i) => ( | |||
<li key={i}>{ingredient.name}</li> | |||
))} | |||
</ul> | |||
<section className="instructions"> | |||
<h2>Cooking Instructions</h2> | |||
{steps.map((step, i) => ( | |||
<p key={i}>{step}</p> | |||
))} | |||
</section> | |||
</section> | |||
); | |||
} | |||
</source> | |||
== React fragments == | |||
<source lang="js"> | |||
function Cat({ name }) { | |||
return ( | |||
<React.Fragment> | |||
<h1>The cat's name is {name}</h1> | |||
<p>He's good.</p> | |||
</React.Fragment> | |||
); | |||
} | |||
// equivalent to | |||
function Cat({ name }) { | |||
return ( | |||
<> | |||
<h1>The cat's name is {name}</h1> | |||
<p>He's good.</p> | |||
</> | |||
); | |||
} | |||
</source> | |||
== Intro to webpack == | |||
* Code splitting | |||
* Minification | |||
* Feature flagging | |||
* Hot module replacement (HMR) | |||
* Modularity | |||
* Composition | |||
* Speed | |||
* Consistency | |||
Installing webpack | |||
<source lang="console"> | |||
$ npm install --save-dev webpack@next webpack-cli | |||
</source> | |||
Installing Babel dependencies | |||
<source lang="console"> | |||
$ npm install babel-loader @babel/core --save-dev | |||
</source> | |||
Specify Babel presets | |||
<source lang="console"> | |||
$ npm install @babel/preset-env @babel/preset-react --save-dev | |||
</source> | |||
= React State Management = | = React State Management = | ||
= Reference = | |||
* [https://react-icons.netlify.com React Icons] | |||
* Personal blogs | |||
** [https://www.leighhalliday.com Leigh Halliday] | |||
** [https://www.robinwieruch.de Robin Wieruch] |