React: Difference between revisions

8,306 bytes added ,  9 October 2019
add personal blogs to references
add personal blogs to references
 
(15 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,366: Line 1,373:
startTicking();
startTicking();
</source>
</source>
= How React Works =
== React elements ==
<source lang="js">
React.createElement("h1", { id: "recipe-0" }, "Baked Salmon");
// <h1 id="recipe-0">Baked Salmon</h1>
// log:
{
  $$typeof: Symbol(React.element),
  "type": "h1",
  "key": null,
  "ref": null,
  "props": {id: "recipe-0", children: "Baked Salmon"},
  "_owner": null,
  "_store": {}
}
</source>
== ReactDOM ==
contains tools necessary to render React element in the browser via '''render''' method
<source lang="js">
const dish = React.createElement("h1", null, "Baked Salmon");
ReactDOM.render(dish, document.getElementById("root"));
</source>
rendering array of elements
<source lang="js">
const dish = React.createElement("h1", null, "Baked Salmon");
const dessert = React.createElement("h2", null, "Coconut Cream Pie");
ReactDOM.render([dish, dessert], document.getElementById("root"));
</source>
== Children ==
<source lang="js">
React.createElement(
  "ul",
  null,
  React.createElement("li", null, "2 lb salmon"),
  React.createElement("li", null, "5 sprigs fresh rosemary"),
  React.createElement("li", null, "2 tablespoons olive oil"),
  React.createElement("li", null, "2 small lemons"),
  React.createElement("li", null, "1 teaspoon kosher salt"),
  React.createElement("li", null, "4 cloves of chopped garlic")
);
// equivalent to
const items = [
  "2 lb salmon",
  "5 sprigs fresh rosemary",
  "2 tablespoons olive oil",
  "2 small lemons",
  "1 teaspoon kosher salt",
  "4 cloves of chopped garlic"
];
React.createElement(
  "ul",
  { className: "ingredients" },
  items.map((ingredient, i) => React.createElement("li", { key: i }, ingredient))
);
</source>
== React Components ==
<source lang="js">
function IngredientsList({ items }) { // destructure items from props
  return React.createElement(
    "ul",
    { className: "ingredients" },
    items.map((ingredient, i) => React.createElement("li", { key: i }, ingredient)
  );
}
const items = [
  "2 lb salmon",
  "5 sprigs fresh rosemary",
  "2 tablespoons olive oil",
  "2 small lemons",
  "1 teaspoon kosher salt",
  "4 cloves of chopped garlic"
];
ReactDOM.render(
  React.createElement(IngredientsList, { items }, null),
  document.getElementById("root")
);
</source>
use functions to create components because class syntax is being deprecated.
= 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 =
= Reference =
* [https://react-icons.netlify.com React Icons]
* Personal blogs
** [https://www.leighhalliday.com Leigh Halliday]
** [https://www.robinwieruch.de Robin Wieruch]