Last active
June 20, 2022 08:22
-
-
Save bbrt3/ccc8d66148091468d20fea503e8a8235 to your computer and use it in GitHub Desktop.
React
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
React's basic components: | |
a) components - they are like functions, we invoke function with some input and they give us some output, | |
- input: props, output: UI | |
- reusable and composable | |
- <Component /> | |
- can manage a private state | |
b) reactive updates | |
- react will react | |
- take updates to the browser | |
c) virtual views in memory | |
- generate html using JS | |
- no html template language | |
- tree reconcililation | |
React components | |
a) Function components | |
- simpler, preferred | |
b) Class components | |
- more powerful | |
*/ | |
// props | |
// immutable | |
const MyComponent = (props) => { | |
return ( | |
<domElementOrComponent /> | |
); | |
} | |
// state | |
// mutable | |
const MyComponent extends React.Component { | |
return ( | |
<domElementOrComponent /> | |
); | |
} | |
// JSX is what gets generated from props + state | |
class Hello extends React.Component { | |
render() { | |
return ( | |
// here we just use HTML, but what react does it translates it to AAA first then to actual browser content | |
// this is JSX, that later gets compiled to browser-friendly code (react api calls) | |
<div className="container"> | |
<h1>Getting started</h1> | |
</div> | |
); | |
} | |
} | |
ReactDOM.render(<Hello />, mountNode); | |
// AAA | |
class Hello extends React.Component { | |
render() { | |
return( | |
React.createElement("div", { className: "container" }), | |
React.createElement("h1", null, "Getting started") | |
); | |
} | |
} | |
ReactDOM.render(React.createElement(Hello, null), mountNode); | |
// REACT COMPONENT's NAME HAS TO START WITH UPPER CASE | |
// if we start with lowercase then react will think that it is html element we are referring to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function logRandom() { | |
console.log(Math.random()); | |
} | |
function Button() { | |
// useState is used for changing element state | |
// a, b = useState() | |
// a => state object (getter) | |
// b => updater function (setter) | |
// since javascript only allows returning one element at the time, we return an array | |
// to go around this limit] | |
// we also need to add const to make it work | |
// useState(0) will set the setCounter to increment counter value | |
// useState is a hook, a hook connects the component with a state | |
const [counter, setCounter] = useState(5); | |
// we can define function callback to pass it on later but we need to do it inside our component, because | |
// we need to have access to our getter and setter | |
const handleClick = () => setCounter(counter + 1); | |
const handleClick2 = function () { | |
setCounter(counter + 1); | |
console.log("test"); | |
} | |
// to execute any code in JSX code we can use {code} | |
// events are case sensitive, so we need to type onClick instead of onclick like in regular html!! | |
// we don't need to invoke the function in {code} block, we just need to pass the pointer to the our function | |
// it is also possible to define the function on the spot | |
// return <button onClick={function logRandom() { | |
// console.log(Math.random()); | |
// }}>{counter}</button>; | |
// OR as an arrow function | |
// <button onClick={() => console.log(Math.random())}>{counter}</button>; | |
return ( | |
// <button onClick={() => setCounter(counter * 2)}> | |
<button onClick={handleClick2}> | |
{counter} | |
</button>); | |
} | |
ReactDOM.render( | |
// single element case | |
<Button />, | |
// multiple element case | |
// exhibit a | |
[<Button />, <Display />] | |
// exhibit b | |
// with DOM parent | |
<div> | |
<Button /> | |
<Display /> | |
</div> | |
// exhibit c | |
// without DOM parent with react.fragment | |
<React.Fragment> | |
<Button /> | |
<Display /> | |
</React.Fragment> | |
// exhibit d | |
// without DOM parent without react.fragment | |
<> | |
<Button /> | |
<Display /> | |
</> | |
// exhibit d | |
// without DOM parent, lazy option | |
document.getElementById('mountNode'), | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{{ var v = 42; }}} | |
{ | |
// block scope | |
{ | |
// nested block scope | |
// let, const | |
// we use const if reference should not change | |
// const means constant reference | |
// not constant value, we can still replace it | |
// with array and objects content of them might change but reference will not! | |
// the more consts the better! :) | |
} | |
} | |
function sum(a, b) { | |
// function scope | |
} | |
for (let i = 1; i <= 10; i++) { | |
// block scope | |
} | |
// if we defined i as var then we could access it after the loop! | |
// Arrow functions | |
const X = function() { | |
// this here is the caller of x | |
} | |
const Y = () => { | |
// this is not caller of Y | |
// it's the same this found in Y's scope | |
} | |
// rules | |
// Regular functions give access to their "calling" environment while arrow functions give access to their "defining" environment | |
// The value of "this" inside a regular function depends on HOW the function was CALLED (OBJECT THAT MADE THE CALL) | |
// The value of "this" inside an arrow function depends on where the function was DEFINED | |
const testerObj = { | |
func1: function() { | |
console.log('func1', this); | |
}, | |
func2: () => { | |
console.log('func2', this); | |
} | |
} | |
testerObj.func1(); | |
testerObj.func2(); | |
// shorter syntax | |
const square = a => a * a; | |
// Object literals | |
const mystery = 'answer'; | |
const inverseOfPi = 1 / Math.PI; | |
const obj = { | |
p1: 10, | |
p2: 20, | |
f1() {}, | |
f2: () => {}, | |
[mystery]: 42, //dynamic property, underneath there will be no property called mystery, but there will be one called answer as defined in the mystery variable above and it's value will be 42 | |
inverseOfPi // short syntax | |
} | |
console.log(obj.mystery); | |
// Destructuring | |
// const PI = Math.PI; | |
// const E = Math.E; | |
// const sqrt2 = Math.SQRT2; | |
const {PI, E, SQRT2} = Math; | |
// const {Component, Fragment, useState} = require('react'); | |
// useState(); | |
const circle = { | |
label: 'circleX', | |
radius: 2 | |
}; | |
// here we extract just the properties that we are interested in from object | |
const circleArea = ({radius}, {precision = 2} = {}) => (PI * radius * radius).toFixed(2); | |
console.log(circleArea(circle)); | |
// {precision = 2} = {} | |
// If we won't provide object that has precision property then it will use empty object that will use default value of 2 as precision | |
// here we skipped third argument so forth will hold value of 40 | |
const [first, second,, forth] = [10, 20, 30, 40]; | |
console.log(second); | |
console.log(forth); | |
// here we want to create new array for elements after the first one | |
//const [first, ...restOfItems] = [10, 20, 30, 40]; | |
const data = { | |
t1 = '1', | |
t2 = '2', | |
name = 'john' | |
}; | |
const {t1, t2, ...person} = data; | |
// shallow copies | |
const newArray = [...restOfItems]; | |
const newObject = { | |
...person | |
}; | |
// Template strings | |
const s1 = 's1'; | |
const s2 = 's2'; | |
// interpolation, dynamic data | |
const s3 = ` | |
<div> | |
${Math.random()} | |
</div>`; | |
// Classes | |
class Person { | |
constructor(name) { | |
this.name = name; | |
} | |
greet() { | |
console.log(`Hello, ${this.name}`); | |
} | |
} | |
class Student extends Person { | |
constructor(name, level) { | |
super(name); | |
this.level = level; | |
} | |
} | |
const p1 = new Person("Max"); | |
const p2 = new Student("Tina", "1st grade"); | |
p2.greet = () => console.log("SPECIAL!"); | |
p1.greet(); | |
p2.greet(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Button(props) { | |
const handleClick = () => props.onClickFunction(props.increment); | |
return ( | |
// function callback is available so we just use it from props | |
// props.onClickFunction(props.increment) is an invocation of a function | |
// and we need a reference so we need to use arrow syntax or another reference | |
<button onClick={handleClick}> | |
+{props.increment} | |
</button>); | |
} | |
function Display(props) { | |
return ( | |
// nowe message is available in properties, we just need to read it | |
<div>{props.message}</div> | |
); | |
} | |
// our components always receive props regardless of if we specify (props) or not! | |
function App() { | |
// stateful property on parent component so children can access it | |
// state should be defined as low in tree closest to children that will need that state as possible | |
const [counter, setCounter] = useState(0); | |
const incrementCounter = (value) => setCounter(counter + value); | |
return ( | |
<div> | |
{/* that's how you comment in JSX */} | |
{/* props can hold functions as well, because its all object in JS */} | |
{/* passing value as {5} will cause it to be numeric, "5" will be a string */} | |
<Button onClickFunction={incrementCounter} increment={1}/> | |
<Button onClickFunction={incrementCounter} increment={5}/> | |
<Button onClickFunction={incrementCounter} increment={10}/> | |
<Button onClickFunction={incrementCounter} increment={100}/> | |
{/* passing prop to component goes by prop={value}*/} | |
{/* here we pass counter */} | |
{/* ONE WAY FLOW OF DATA */} | |
<Display message={counter}/> | |
</div> | |
); | |
} | |
ReactDOM.render( | |
<App />, | |
document.getElementById('mountNode'), | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const render = () => { | |
document.getElementById('mountNode').innerHTML = ` | |
<div> | |
Hello HTML | |
<input /> | |
${(new Date).toLocaleTimeString()} | |
</div> | |
`; | |
ReactDOM.render( | |
React.createElement( | |
'div', | |
null, | |
'Hello React', | |
React.createElement('input', null), | |
React.createElement('p', null, (new Date).toLocaleTimeString()) | |
), | |
document.getElementById('mountNode2'), | |
); | |
} | |
// react only updates what needs to be updated | |
// with regular dom everything gets updated | |
// no imperative logic | |
setInterval(render, 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment