ReactJS Notes

Page Contents

Course Notes

These are notes from the Udemy course React - The Complete Guide by Maximilian Schwarzmüller. It's a great course, give it a go!

Intro

react
react-dom

babel - translate next gen javascript to browser compatible javascript


react component is just a function that has to return the code to render to the dom
	JSX - needs babel as the preprocessor that converts JSX to normal javascript code
	JSX - requires one root div!

function Person(props) { // React auto gives me the props parameter - the component properties.
	return (
		<div className="person"> // NOTE: use of className not class! This is JSX thing - class is a reserved word in JS so cant be used.
			<h1>{props.name}</h1>
			<p>Some stuff: {stuff}</p>
		</div>
	);
}
ReactDOM.render(<Person name="John" stuff="Whatever"/>, document.querySelector('#p1')); - render a javascript function as a component to the real dom inside div with id "p1"


Could also do
	app = (
		<div>
			<Person name="John" stuff="blah"/>
			<Person name="Peter" stuff="blah"/>
		</div>
	);
	ReactDOM.render(app, document.querySelector('#app')); # A single page application

React focusus on the what not the how - focus on what you want to see rather than managing individual UI state and keeping track of it all.



Todo / To Read / Good Reads

https://blog.bitsrc.io/understanding-react-render-props-and-hoc-b37a9576e196
https://kentcdodds.com/blog/application-state-management-with-react
https://www.youtube.com/watch?v=3XaXKiXtNjw&ab_channel=ReactTraining
https://kentcdodds.com/blog/prop-drilling
https://kentcdodds.com/blog/state-colocation-will-make-your-react-app-faster
https://kentcdodds.com/blog/how-to-use-react-context-effectively
https://pagepro.co/blog/how-to-use-memoization-in-js-and-react/#:~:text=First%20things%20first%2C%20Memoization%20in,same%20arguments%20are%20supplied%20again.
https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
https://indepth.dev/posts/1501/exploring-how-virtual-dom-is-implemented-in-react
https://vaadin.com/learn/tutorials/using-web-components-in-react
https://felixgerschau.com/react-component-composition/
https://codewithnico.com/production-ready-react-apps/
https://github.com/chaoming/fireact



Some Resources

create-react-app: https://github.com/facebookincubator/create-react-app
Introducing JSX: https://reactjs.org/docs/introducing-jsx.html
Rendering Elements: https://reactjs.org/docs/rendering-elements.html
Components & Props: https://reactjs.org/docs/components-and-props.html
Listenable Events: https://reactjs.org/docs/events.html



Setup Local React Project

Build a workflow - optimize code, lint, make code cross-browser compatible using babel and jsx etc.
Need - dependency management tool, e.g. npm
       bundler - put all our JS modules into one file - use webpack
       compiler - next-gen JS to older-JS = babel + presets
       dev server to test on
^^^^
There is a react-team supported tool that does all this for us! -- `npm install -g create-react-app` -
only using nodeJS for the package manager and the dev server
	Use command create-react-app react-complete-guide --scripts-version 1.1.5
		Creates a folder called `react-complete-guide` in the CWD

CD into `react-complete-guide` and type `npm start` to start the development server. It server
watches your files so if you change code it will auto-reload it for you!
	Inside that directory, you can run several commands:
	  npm start
	    Starts the development server.
	
	  npm run build
	    Bundles the app into static files for production.
	
	  npm test
	    Starts the test runner.
	
	  npm run eject
	    Removes this tool and copies build dependencies, configuration files
	    and scripts into the app directory. If you do this, you can’t go back!

			tip: Try out `Rescripts`, which is used to modify create-react-app's webpack configuration,
			without ejecting the app... woop woop! (https://github.com/harrysolovay/rescripts)



React Component Basics

Every component needs a `render()` method - it returns an object that react can use to render 
content to the HTML DOM.

> Components are the core building block of React apps. Actually, React
> really is just a library for creating components in its core.
> A typical React app therefore could be depicted as a component tree -
> having one root component ("App") and then an potentially infinite amount
> of nested child components.
> Each component needs to return/ render some JSX code - it defines
> which HTML code React should render to the real DOM in the end.


JSX v.s. React
--------------
JSX is a syntactic sugar that needs to be translated into javascript code.

For example "<div></div>" would be translated into
	React.createElement('div', props-object, child1 [,child2[,...]]),
where the children are also created using React.createElement(...).

JSX restrictions
1. Cannot use JS reserved keywords
2. Must have ONE root element, normally a DIV.
	- The way round this is to use a HOC that just returns its children.
	- In react > 16.2 you dont have to create this HOC yourself - its is provided and is called
	  "React.Fragment".


Creating Basic Components
-------------------------
Directory and file(s) in that directory for each component with same name as componenet, normally
using capitalised first letter.
In file
  - import React from 'react.js';
  - const component_name = (...) => { return SOME-REACT-ELMENTS-VIA-JSX; }
  - export default component_name;

In root component file:
  - import Component_name from './Comonent_name/Component_name.js' <- Name must have upper-case
    character because elements starting lower case are reserved for HTML reserved node names
  - then use <Component_name>...</Componeent_name>

To get JSX code to execute and use the output of a JS function (can only use one-line expressions),
wrap the code in curley braces - {}

	Props
	-----
	Allow us to pass attributes (and children) specified in the JSX/HTML code to the JS component so
	that it can display content dynamically. Note the props object passed to the componenet should 
	*NOT* be modified by the component.

	If component is constructed using a function, the function gets one parameter - the props obejct.
		const componenet_name = (props) => {
			return <div>
				<p>I am {props.age} years old.</p>
				<p>I live in the country {props.country}</p>
			</div>; 
		};
	If componeent is constructed using a class then in the render() method use `this.props.age` for
	example. The props are passed automatically made available as `this.props` for you.

	To access children, e.g. <Component_name>Some text in the middle</Component_name>, use `props.children`,
	which is created by react for us. It will contain all elements between the opening and closing
	tags of the component, plain text, or an element tree...

	You can pass METHODS as props so that other componenets can access methods, from say, the main app,
	for example. This could allow a child componenet to change data in the parent component. It is a
	useful pattern.

	!!!! Whether you declare a component as a function or a class, it must never modify its own props. !!!!

	State
	-----
	Only for classes exending `Component` (and see also React hooks for function based components) PRE React 16.8. 
		Function based components can, since React 16.8, use the useState() hook
	Create a class variable named `state`, which should be a JS oject with keys, as you want to define
	them, mapping to values of interest. The variable is SPECIAL because if it changes it will triger
	React to re-render the DOM with the updated data BUT ONLY IF YOU USE `this.setState()`.

	!! NOTE you must use `this.setState()` to TRIGGER RE-RENDERING OF DOM !! Do not modify the state variable directly !!
		setState() takes an object as argument and merges it with the class state object for us.

	!! NOTE THE FOLLOWING !!
	!!
	!!	It does not immediately trigger the render, it merely schedules a render, so the state won't be
	!!	updated until React determines it is a "good time" to do that.
	!!
	!!	Because of this, "this.state" in "setState()" is NOT GUARANTEED TO BE THE LASTEST/NEWEST
	!!	STATE OF THE OBJECT!!!! It could be an older state. This is because React may batch multiple
	!!	setState() calls into a single update for performance.
	!!
	!!  See: https://reactjs.org/docs/state-and-lifecycle.html
	!!  See rationale for async setState: https://github.com/facebook/react/issues/11527#issuecomment-360199710
	!!
	!!	This means using setState like this can sometimes cause problems:
	!!		someFunc = () => {
	!!			setState({something: this.state.something + 1});
	!!			//                  ^^^^^^^^^^
	!!			//                  WARNING - this could be a STALE STATE
	!!		};
	!!
	!! The correct way to do this is as follows:
	!!		someFunc = () => {
	!!			setState((prevState, props) => {
	!!				return {
	!!					something: prevState.something + 1;
	!!				};
	!!			});
	!!		};
	!!
	!! This uses the alternative setState syntax which accepts a function that receives the previous
	!! state and the component's props. React can then call this function when it is ready to set
	!! a new state. Then prevState that is passed to this function is GUARANTEED BY REACT TO BE THE
	!! MOST RECENT STATE THAT YOU WOULD NORMALLY EXPECT.


	Generally on PROPS and STATE cause react to re-render the DOM.

	Anything using state is a statefull componenet. Otherwise it is stateless. Design to have few as
	possible statefull and as many as possible stateless (presentation) components.

	!!!! YOU SHOULD NEVER MUTATE THE STATE VARIABLE - ALWAYS TAKE COPIES, ESP FOR ARRAYS ETC, AND THE CALL setState() !!!!
		It is MUCH BETTER TO TAKE A **COPY** of the arrayMember, mutate it, and then setState()!
		Instead use slice() with no params to copy array:
			const arrayMemberRef = this.state.arrayMember.slice(); // Now arrayMemberRef references a COPY of the reactJs-managed state variable
		OR use ES6 spread operator:
			const arrayMemberRef = [...this.state.arrayMember]; // Now arrayMemberRef references a COPY of the reactJs-managed state variable

		The same is true if the member is an object - you'd get a reference, not a copy of the object.
		Take a copy using:
			const objectmemberRef  = {...this.state.objectReference };
		OR old-school using Object.assign().



Events & Handlers

All HTML attributes like onclick become onClick in JSX.
See https://reactjs.org/docs/events.html#supported-events

In a class that extends `Component`, define arrow function for eventHandler (use arrow function to
correctly capture "this"). Then do , for e.g., <button onClick='this.eventHandler'>...</button>. When
the button is clicked it will call the function `eventHandler()` of your class, which if it then
modifies the class state, will cause the component to be re-rendered into the DOM.

To pass data to a handler use the bind() method.
	<button onClick={this.myHandler.bind(this, param1, param2, ...)>
If you've used arrow functions the binding to this isn't necessary - the arrow function will have
captured it, but because we want to bind other parameters, we now have to have this as the first
parameter to bind(). This is why with arrow functions we don't have to use bind() if there is no
extra data to pass into the handler.

The other way to accomplish this is to use an arrow function, and it looks a little nicer IMO, BUT BUT
apparently it can be less efficient and bind() is therefore preferred.
	<button onClick={() => this.myHandler(param1, param2, ...)}>


Handling Events
---------------
https://reactjs.org/docs/events.html
https://reactjs.org/docs/handling-events.html

* React events are named using camelCase, rather than lowercase.
* React event handlers are passed instances of SyntheticEvent, a cross-browser wrapper around the 
  browser's native event. Same interface as the browser’s native event.
    * 'nativeEvent' attribute to get underlying browser event object.
* SyntheticEvents are pooled. 
* With JSX you pass a function as the event handler, rather than a string.
* Cannot return false to prevent default behavior in React. You must call preventDefault explicitly.

From https://stackoverflow.com/a/53500357:
	Wrapping native event instances can cause performance issues since every synthetic event wrapper
	that's created will also need to be garbage collected at some point, which can be expensive in
	terms of CPU time.

	React deals with this problem by allocating a synthetic instance pool. Whenever an event is triggered,
	it takes an instance from the pool and populates its properties and reuses it. When the event
	handler has finished running, all properties will be nullified and the synthetic event instance is
	released back into the pool. Hence, increasing the performance.



Hooks

All React hooks are called "useXXX".
	import React, {useXXX, useYYY, ...} from 'react';

useState() hook
---------------
So, now instead of using class `state` variable, in function-based componenet do:
	const app = (props) => {
		const [ theCurrentState, theSetStateFunction ] = useState({... state object defn ...});
Now, where you would use `this.state` use `theCurrentState` and where you would use `setState()`
use `theSetStateFunction()`.

And in your handler functions, just put them inside the component defn function and reference the
function in the JSX returned. NOTE - the handler must be an arrow function so that it is lexically
scoped and captures `theCurrentState` and `theSetStateFunction` in the enclosing compononent def func.

		const app = (props) => {
			const [ theCurrentState, theSetStateFunction ] = useState({... state object defn ...});
			const myHandler = () => {
				theSetStateFunction({...});
			}
			return JSX-which-has-myHandler-as-an-onXXX-function;
		};

	!!!!BUT CAUTION!!!! theSetStateFunction() does **NOT** do a merge like setState() does. 
	You must do the merge yourself manually! But you can get around this with many useSate() calls - state "slices".

This is a new way - the class based method is still seemingly the standard.



Css

Import into your JS files so that WebPack is aware of its existance. Put CSS for component in
component's dir and use class name same as component's name.

For things like "box-shadow" it converts this CSS property to the difference browser variables for
us like "-webkit-box-shadow" and "box-shadow" for us so our CSS can be more brief and generic.

	Inline styles
	-------------

	The style can be modified in the JS using inline styles. The CSS code ports almost directly to a JS
	object definition except REPLACE "-" WITH CAMEL CASE
		e.g. 
		render() {
			const style = {
				backgoundColor:'white',
				border:'1px solid blue',
				...
			};

			return ( <div style={style}>.....</div> );
		}


	CSS Modules
	-----------
	See https://github.com/css-modules/css-modules
	See https://css-tricks.com/css-modules-part-1-need/
	See https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/

	A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.
	It does this by automatically creating a unique classname of the format [filename]_[classname]__[hash].
	This automatically creates CSS names that would look a lot like the names you might create if you are
	using the BEM CSS naming in a non-react project where you need to name you classes to identify the
	blocks they refer to etc.

	Use CSS module like this:
		import styles from './Button.module.css'; // Import css modules stylesheet as styles
		...
		class Button extends Component {
			render() {
				// reference as a js object
				return <button className={styles.Error}>Error Button</button>;
				//                        ^^^^^^^
				//                        Gets locally scoped error CSS from sytems imported above.
				//                        So CSS has a def `.error: {...}`
			}
		}

	Can also specify an array for `className` to apply many classes to an object, using the normal
	string with spaces, by joining elements of an array. E.g.:
		<button className={[styles.Error, styles.Big].join(" ")}>...</button>

	Can specify which style dynamically by using `styles['Big']`, e.g.:
		<button className={[styles.Error, styles[props.btnSize]].join(" ")}>...</button>

	NOTE: react-scripts >= 2.0 you do NOT have to eject and CSS modules must be  `*.module.css`.

	For react -scripts < 2.0, to enable CSS modules (required for react-scripts < 2.0). 
		1. npn run eject
			From https://github.com/facebook/create-react-app/blob/master/packages/cra-template/template/README.md:
				Note: this is a one-way operation. Once you eject, you can’t go back!

				If you aren’t satisfied with the build tool and configuration choices, you can eject
				at any time. This command will remove the single build dependency from your project.

				Instead, it will copy all the configuration files and the transitive dependencies
				(webpack, Babel, ESLint, etc) right into your project so you have full control over them.
				All of the commands except eject will still work, but they will point to the copied scripts
				so you can tweak them. At this point you’re on your own.

			The eject command will have created a new top level directory, called "config" for you,
			which has received the above mentioned script copies. The "package.json" file will now
			also be A LOT larger. You can now see _all_ of your dependencies in detail.

		2. Goto "ROOT/config/webpack.config.dev.js"
			Search "css-loader". You should see:
				{
					test: /\.css$/,
					use: [
						require.resolve('style-loader'),
						{
							loader: require.resolve('css-loader'),
							options: {
								importLoaders: 1,
							},
						},
						...

			Add the following options, under "importLoaders":
							options: {
								importLoaders: 1,
								modules: true,
								localIdentName: '[name]__[local]__[hash:base64:5]',
							},
			
			Copy these two options into the production build file too!

		This is all that is required. CSS modules should now be good to go!

	Using Web Fonts
	---------------
	You can add includes of web fonts to "ROOT/Public/index.html".
	Goto fonts.google.com, select and customise the font that you like, get the CDN link and shove
	it into index.html above the title tag.



Conditional Rendering

In JSX we can execute simple JS expressions in {...}. This means that we could render based on the
ternary operator "cond ? true-path : false-path". Note cannot use if-else as this is
too complicated. Could we use a function and immediately evaluate it though? Not sure - need to try.
E.g.,
	return (
		<div>
			{
				this.state.someCondition ?
					<div>
						... some tags ...
					</div> : null // "null" means nothing is rendered
			}
			...
		</div>
	);

^^^
This gets MESSY fast, especially when multiple conditions are nested. It is BETTER to do the FOLLOWING:

	let myElements = null;
	if(this.state.someCondition)
	{
		myElements = (
			<div>
				... some tags ...
			</div>
		);
	}

	...

	return (
		<div>
			{myElements}
		</div>
	);
^^^
This is EASIER TO READ AND MAINTAIN! Keeps our core JSX template CLEAN!



Rendering Lists

If the state, or whatever other variable has a list of attributes for a list of like-tags we can do this:
	return (
		<div>
			{this.state.listMember.map((member, index) => {
				return <TheElement
					somehandler={someHandlerFunction.bind(this, index)}
					prop1={member.prop1}
					prop2={member.anotherProp} 
					key={index} /> // You SHOULD ALWAYS PROVIDE A KEY!!
			})}
		</div>
	);

The map() funciton returns an array - JSX knowns how to render a list of ReactElement objects so this works okay.

NOTE -	arrays are references to an array - so 
		const arrayMemberRef = this.state.arrayMember; // Gets a reference to the state.arraymember!!
		arrayMemberRef[0] = 123; // !!!!WARNING!!!! This mutates the reactJs managed state object which can produce UNDERIABLE BEHAVIOUR
		this.setState({arrayMember : arrayMemberRef});
	It is MUCH BETTER TO TAKE A **COPY** of the arrayMember, mutate it, and then setState()! Instead use slice() with no params to copy array:
		const arrayMemberRef = this.state.arrayMember.slice(); // Now arrayMemberRef references a COPY of the reactJs-managed state variable
	OR use ES6 spread operator:
		const arrayMemberRef = [...this.state.arrayMember]; // Now arrayMemberRef references a COPY of the reactJs-managed state variable


NOTE -	When rendering lists of data ALWAYS USE THE KEY PROP. It helps react know what changed in the list more efficiently.



Use Pseudo Selectors In Javascript

Requires package called "Radium"
	From your project directory: npn install --save radium
	Radium lets pseudo selectors and media queries be used from the JS
	> import Radium from 'radium';

	Then
		> export default Radium(App)
		To create a higher order componenet. Radium wraps you App. It can wrap both classes and
		function-based componenets.

With radium installed you can add the following to your style objects in JS code:
	const style = {
		color: 'white',
		...,
		':hover': {
			... set of styles for the hover state ...
		},
		':another-pseudo-selector' : {
			... another set of styles ...
		},
	};

You can also do media queries in the same way, EXCEPT you will have to use <StyleRoot> around your App:
In any componenet(s) you like:
	const style = {
		...
		'@media (min-width: 500px)': {
			...
		},
		...
	};
Then in your app:
	import Radium, { StyleRoot } from 'radium';
	...
	class App extends Component {
		...
		render() {
			return (
				<StyleRoot>
					... your original app content JSX ...
				</StyleRoot>
			);
		}
	}



Styled Componenets

styled-components.com
Tries to make styling components easy.
Do:
	npn install --save styled-componenets

Use:
	import styled from 'styled-componenets.js';

	const StyledButton = styled.button`
		../ write regular CSS within the back ticks ...
	`;

	const StyleDiv = styled.div`
		../ write regular CSS within the back ticks ...
		&:hover { // <<<< Special way to add pseudo element styles using styled componenets
		}

		color: ${props => props.altColour}; //<<< Note use of ${...} to access props
	`;

	...

	class ....
	{
		...
		render() {
			...
			return(
				<!-- Note how props can be passed to styledComponents for dynamic CSSS -->
				<StyledDiv altColor={this.state.my_colour_variable}> 
					<StyledButton onClick={...}/>
					...
				</SyledDiv>
			);
		}
		...
	}

People seem to like this because you get scoped styles - I.e., they apply only to the component not
to the entire application.

BUT - you are now mixing markup with code, which was the entire point of CSS/HTML seperation in the first place!
BETTER? - Use CSS Modules - Haven't written notes on this...



Error Boundaries

See: https://reactjs.org/docs/error-boundaries.html
Only availabele in ReactJS >= 16
Allow us to catch errors (exceptions) and handle them gracefully.
They are a form of Higher Order Component (HOC) they wrap the componenet that may throw an error. Notes on this later.
	class ErrorBoundary extends Componenet {
		state = {
			hasError: false,
			errorMsg: '',
		}
		
		// this is a special method that react knows to call if any of the children
		// throw an exception
		componenetDidCatch(error, info) {
			this.setState({hasError: true, errorMsg: error});
		}

		render() {
			if (this.state.hasError) {
				// If there was an error render something usful
				return <h1>{this.state.errorMsg}</h1>;
			}
			else {
				// Otherwise just display the components this component wraps
				return this.props.children;
			}
		}
	}

Then in your App render or whatever, just wrap any elements that may have failures that are _not_ under
your control (i.e. dont wrap everything - you want to catch errors that are under your control and
make sure thay cannot happen) with <ErrorBoundary>....</ErrorBoundary> (class name just an example -
you can choose).



Class Based V.S. Functional Components

Class based
	Access to state
	Lifecycle Hooks

Functional based
	ReactJS <16 _no_ access to state, but .+ 16 has access to state via useState()
	_No_ access to lifecycle hooks



Class Component Lifecyle

See also https://reactjs.org/docs/state-and-lifecycle.html
         https://reactjs.org/docs/react-component.html
         https://www.w3schools.com/react/react_lifecycle.asp
         https://www.freecodecamp.org/news/how-to-understand-a-components-lifecycle-methods-in-reactjs-e1a609840630/
         https://blog.carbonfive.com/replacing-component-lifecycle-methods-with-react-hooks/
         >> Good diagram >> http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

Functional component have an equivalent but this is for class based components only.
ReatcJS components have the following LIFE CYCLE HOOKS methods:
	- constructor(props) (default ES6 class feature, unlike the rest which are React specific)
	- static getDerivedStateFromProps(props, state)
              should return updated state
	- getSnapshotBeforeUpdate(prevProps, prevState)
	- componenetDidCatch()
	- componentWillMount() [might be deprecated]
	- componentWillUnmount()
		This can be used to do cleanup work like de-register event handlers etc.
	- shouldComponentUpdate(nextProps, nextState)
	- componentDidUpdate(prevProps, prevState, snapshot)
             After the update finished. The one that is most used is this method, e.g., to fetch
             new data from server.
	- componentDidMount()
	- render()

Note: Life-cycle hooks are not, and have nothing to do with, React Hooks.


Creation life cycle hooks execute in this sequence:
CREATION --> constructor(props) [must call super(props). Set state. Must have NO side-effects]
                constructor(props) {
                    super(props);
                    ... do other init stuf ...
                    // Can init state here - but dont call setState() as there is nothing to merge with yet
                    this.state = { ... };
                }
         --> getDerivedStateFromProps(props, state) [Sync state when props changed - niche. Must have NO side-effects]
         --> render() [Prepare and structure JSX code. Nothing that blocks!]
             --> render all child components and run their life cycle hooks...
         --> componentDidMount() [Do NOT update state (synchronously), but DO cause side effects, eg, HTTP requirets]



Component update (when props or state change) life cycle hooks execute in this sequence:
UPDATE --> getDerivedStateFromProps(props, state) [rarely needed]
       --> shouldComponentUpdate(nextState, nextProps)
           [Allows us to CANCEL the update process for optimisation. Do NOT cause side effects]
               Must return either True (do the update) or false (cancel the update)
       --> render() [constructs virtual DOM for merge into the real DOM]
           --> render all child components and run their life cycle hooks...
       --> getSnapshotBeforeUpdate(prevProps, prevState)
               Must return either null or an object, which will be received in componenetDidUpdate
               Example might be getting current scroll position so it can be restored in next step.
       --> componentDidUpdate(prevProps, prevState, snapshot)
           [NO (synchonous) state update but can cause side effects]


shouldComponentUpdate() is the one you will use for OPTIMISATION!

	Optimising using shouldComponentUpdate()
	----------------------------------------

	If a parent component updates, but the specific child has not updated (another child or the main
	element might have), then it can use shouldComponentUpdate() to stop itself needlessly being rendered
	into the ReactJS virtual DOM.

	For example,
		shouldComponentUpdate(nextProps, nextState) {
			// Bit note - be careful - this compares references, so if the references dont change
			// but the contents does, then this wont work! This is a SHALLOW comparison!
			return nextProps.propsOfInterest !=  this.props.propsOfInterest;
		}



Functional Hooks

See: https://reactjs.org/docs/hooks-effect.html
     https://medium.com/swlh/react-lifecycle-hooks-71547ef4e7a8
     https://blog.carbonfive.com/replacing-component-lifecycle-methods-with-react-hooks/

	> By using this Hook, you tell React that your component needs to do something after render.
	> React will remember the function you passed (we’ll refer to it as our “effect”), and call it
	> later after performing the DOM updates.

Use the "useEffect()" hook.
	import React, { useEffect } from 'react';

useEffect() is the second most important reactJS hook next to the useState() hook.
It combines all of the class hooks above into one function. It is _not_ a lifecycle hook, however,
it is a react hook!

useEffect() takes a function as an argument that is called for each render cycle.

Can be used for all the stuff that would be done in "componentDidUpdate()", e.g., a HTTP req. It
also does "componentDidMount()" (called for the first render).

You can use "useEffect()" as many times as you like.

	useEffect( () =>  {
		... do stuff ...
	}, [list-of-data])
	   ^^^^^^^^^^^^^^
	   Secnd argument to useEffect()
	   It is a list of references to all of the data used in the function. The function will only
	      run when a data item in this list changes.
	      So, if we use "props.member", it would only be called when the props change.

	      If you have different effect that depends on different data just use the function more
	      than once.

	      To make the "useEffect()" run only once, when it is created, just pass a second argument
	      that is an empty list - []. As there are no dependencies for the func, therefore, it will
	      never be re-run because a dependency change. But, it will run once at creation.

	> You can tell React to skip applying an effect if certain values haven’t changed between
	> re-renders. To do so, pass an array as an optional second argument to useEffect

If "useEffect()" returns a function, this function is run after the render cycle. Thus, you can
return a function if you want to do some cleanup.

	useEffect( () => {
		... do stuff ...
		return () = > {... do cleanup work ...};
	}, []) // The empty list only renders this when the component is created, not on every render cycle


	Optimisation
	------------

	Use React.memo() to wrap your functional component to memo-ise it!



When To Optimise

Not always is the answer! If child always updates with parent then no need to optimise and using
either shouldComponenetUpdate or react.memo() is actually inefficient as they will always find that
the component changes - so its extra work for no reason.

If you care checking ALL proprties for change, you don't need to override shouldComponentUpdate().
You can, instead, extend PureComponent. This is just a component that a component that
implements shouldComponentUpdate() and checks for any change in props.



How Reactjs Updates The Dom

See: https://reactjs.org/docs/faq-internals.html
See: https://reactjs.org/docs/reconciliation.html

ReactJS render() method does _not_ render to the DOM. It edits a ReactJS internal DOM. React compares
the old vidtual DOM to the new virtual DOM and diffs them. The virtual DOM is used because it is
_faster_ than the real DOM. Acessing the deal DOM is s-l-o-w!!

If the diff of the VDOMs shows a difference, only then does React reach
out to the real DOM and updates it - and _only_ in the places where it updated, it does _not_ re-write
the entire DOM.

million.js.org has a good explanation of a VDOM:
	The virtual DOM is a tree of virtual nodes that represents what the DOM looks like. virtual nodes
	are light, stateless, and are strings or JavaScript objects that only contain necessary fields.
	Virtual nodes can be assembled into trees, and "diffed" to make pinpoint changes to the DOM.

	The reasoning behind this is because modification and access of DOM nodes is computationally
	expensive. A diff between virtual nodes, accessing the DOM only for modification, is the premise
	of virtual DOM. It avoids the DOM as much as possible, favoring plain JavaScript objects instead,
	making reading and writing much cheaper.

react docs, of course, also gave good explanation:
	The virtual DOM (VDOM) is a programming concept where an ideal, or "virtual", representation of
	a UI is kept in memory and synced with the "real" DOM by a library such as ReactDOM. This
	process is called reconciliation.

	This approach enables the declarative API of React: You tell React what state you want the UI
	to be in, and it makes sure the DOM matches that state. This abstracts out the attribute
	manipulation, event handling, and manual DOM updating that you would otherwise have to use
	to build your app.

	Since "virtual DOM" is more of a pattern than a specific technology, people sometimes say
	it to mean different things. In React world, the term “virtual DOM” is usually associated with
	React elements (elements are the smallest building blocks of React app and describe what you
	want to see on the screen. eg. const el = <b>Me</b>) since they are the objects representing the
	user interface. React, however, also uses internal objects called "fibers" to hold additional
	information about the component tree. They may also be considered a part of "virtual DOM"
	implementation in React.

	Fiber is the new reconciliation engine in React 16. Its main goal is to enable incremental
	rendering of the virtual DOM.



Higher Order Components (Hocs)

A HOC wraps another component, possibly adding some logic to it etc. For e.g., error handling.
Convention is to name Hocs with a "With" at the beginning. e.g. "WithExtraInfo".

Create HOC method #1:
---------------------
	Use for HOCs that modify the HTML of the component in some way - so you can place it inside
	your JSX.
	Do:
		import React from 'react';
		const withBlah = props => (
			<div className="blah">
				... what ever extra components you want ...
				{props.children} <!-- <<<< This is what we're wrapping -->
				... what ever extra components you want ...
			</div>
		);
		export default withBlah;

	Then you use it in another component:
		import withBlah from 'react';
		...
		<WithBlah>
			...
		</WithBlah>

Create HOC method #2:
---------------------
	Use for HOCs that add behind the scenes logic like error handling.
	Do:
		import React from 'react';
		// Normal JS function
		const withBlah = (WrappedComponent, param1, param2, ...) = {
		               // ^
		               // Must start with a capital
			// From the normal JSX function, return the React component function.
			return props => (
				<div className="blah">
					<WrappedComponent {...props}/>
					<!-- NOTE: You cannot use props={props} because the Wrapped component would
					     receive this as props.props, an child of its props component. Hence
					     you have to use the spread operator as shown -->
				</div>
			);
		};

	Then you use it to wrap a component in an export:
		...
		export default withBlah(App, param1, param2, ...);



Prop Types

See https://reactjs.org/docs/typechecking-with-proptypes.html

Allows to specify which props the component accepts and their props.
	npm install --save prop-types
It is provided by the react team/community. It is not in react core hence you have to npm install it.
Then:
	import PropTypes from 'prop-types';
Then, after your component definition, whether functional or class based, add another property.
	class MyComponent {
		...
	};

	// React will look for "propTypes" when in development mode and spit out warnings if the prop
	// types are violated.
	MyComponent.propTypes = { // Lower case "p" for "propTypes" is important
		// In here define the props that are used by your component and their types...
		// The keys will be your prop names and their values the types
		click: PropTypes.func, // You can even specify the function prototype!
		prop1: PropTypes.string,
		prop2: PropTypes.number,
		...
	};

Can chain conditions. E.g.
	prop1: PropTypes.string.isRequired

Can also be applied to function components in exactly the same way.

Component children, i.e., `props.children` shold also be put into the propTypes spec.
	static propTypes = {
			children: PropTypes.oneOfType([
					PropTypes.arrayOf(PropTypes.node),
					PropTypes.node
			]).isRequired
	}
(See https://stackoverflow.com/a/42122662/1517244)


Arrays of shapes:
	MyComponent.propTypes = {
		items: PropTypes.arrayOf(
			PropTypes.shape({
				code: PropTypes.string,
				id: PropTypes.number,
			})
		),
	};

Directly from the docs:
	import PropTypes from 'prop-types';

	MyComponent.propTypes = {
		// You can declare that a prop is a specific JS type. By default, these
		// are all optional.
		optionalArray: PropTypes.array,
		optionalBool: PropTypes.bool,
		optionalFunc: PropTypes.func,
		optionalNumber: PropTypes.number,
		optionalObject: PropTypes.object,
		optionalString: PropTypes.string,
		optionalSymbol: PropTypes.symbol,

		// Anything that can be rendered: numbers, strings, elements or an array
		// (or fragment) containing these types.
		optionalNode: PropTypes.node,

		// A React element.
		optionalElement: PropTypes.element,

		// A React element type (ie. MyComponent).
		optionalElementType: PropTypes.elementType,

		// You can also declare that a prop is an instance of a class. This uses
		// JS's instanceof operator.
		optionalMessage: PropTypes.instanceOf(Message),

		// You can ensure that your prop is limited to specific values by treating
		// it as an enum.
		optionalEnum: PropTypes.oneOf(['News', 'Photos']),

		// An object that could be one of many types
		optionalUnion: PropTypes.oneOfType([
			PropTypes.string,
			PropTypes.number,
			PropTypes.instanceOf(Message)
		]),

		// An array of a certain type
		optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

		// An object with property values of a certain type
		optionalObjectOf: PropTypes.objectOf(PropTypes.number),

		// An object taking on a particular shape
		optionalObjectWithShape: PropTypes.shape({
			color: PropTypes.string,
			fontSize: PropTypes.number
		}),

		// An object with warnings on extra properties
		optionalObjectWithStrictShape: PropTypes.exact({
			name: PropTypes.string,
			quantity: PropTypes.number
		}),

		// You can chain any of the above with `isRequired` to make sure a warning
		// is shown if the prop isn't provided.
		requiredFunc: PropTypes.func.isRequired,

		// A value of any data type
		requiredAny: PropTypes.any.isRequired,

		// You can also specify a custom validator. It should return an Error
		// object if the validation fails. Don't `console.warn` or throw, as this
		// won't work inside `oneOfType`.
		customProp: function(props, propName, componentName) {
			if (!/matchme/.test(props[propName])) {
				return new Error(
					'Invalid prop `' + propName + '` supplied to' +
					' `' + componentName + '`. Validation failed.'
				);
			}
		},

		// You can also supply a custom validator to `arrayOf` and `objectOf`.
		// It should return an Error object if the validation fails. The validator
		// will be called for each key in the array or object. The first two
		// arguments of the validator are the array or object itself, and the
		// current item's key.
		customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
			if (!/matchme/.test(propValue[key])) {
				return new Error(
					'Invalid prop `' + propFullName + '` supplied to' +
					' `' + componentName + '`. Validation failed.'
				);
			}
		})
	};

It seems one can kinda use PropTypes with contexts: Ref: https://codesandbox.io/s/1z1oxpx02j:
const TestingContext = React.createContext("light");

	TestingContext.Provider.propTypes = {
		value: PropTypes.oneOf(["light", "dark"])
	};

	const Testing = () => (
		<TestingContext.Consumer>{value => <h1>{value}</h1>}</TestingContext.Consumer>
	);

	const App = () => (
		<div>
			<TestingContext.Provider value="light">
				<Testing />
			</TestingContext.Provider>
			<TestingContext.Provider value="dark">
				<Testing />
			</TestingContext.Provider>

			{/* PropTypes warning since value 'asdf' doesn't match propTypes rule */}
			<TestingContext.Provider value="asdf">
				<Testing />
			</TestingContext.Provider>

			{/* default value used since it's not wrapped in a Provider */}
			<Testing />
		</div>
	);



Using React References

References give us access to our DOM elements.

	IN CLASS BASED COMPONENTS
	-------------------------

	Can add a "ref" keyword to any components, including your own defined components.
	It gives you the ability to access an element in the DOM without having
	to use DOM selectors to find it in the DOM. React magically ties your component class with the
	object in the DOM. You can use this to call DOM specific stuff like "setFocus()" for example.

	Lets say you have a component:
		class MyComponent extends Component {
			constructor() {
				super(); // Must always capp super()!!
				this.inputReference = React.createRef();
			}

			componentDidMount() {
				this.inputReference.current.focus();
				//                  ^^^^^^^ ^^^^^
				//                  ^^^^^^^ We can access the DOM function :)
				//                  ^^^^^^^
				//                  Must use the "current" property to get the current reference.
			}

			render() {
				<div>
					...
					<input
						ref={this.inputReference}
						...
					/>
					...
				</div>
			}
		};

	IN FUNCTIONAL COMPONENTS
	------------------------
	const myFuncComponent = props => {
		const elementRef = React.useRef(null);
		//    ^^^^
		//    elementRef will only be linked to the html_element when the return statement is
		//    executed. Therefore it can only be accessed after this. To do this, the useEffect()
		//    hook must be used, as this runs _after_ the compoment JSX has been rendered for the
		//    first time.

		useEffect( () => {
			elementRef.someDOMFunction(...);
			return () => {
				// This function is run to do cleanup work in useEffect()
			};
		}, []);
		// ^^
		// RECALL: the empty list means this only runs once when first rendered and _not_ on each
		//         render!

		return (
			<div>
				<html_element ref={elementRef}>...</html_element>
			</div>
		);
	};



Context Api & Prop Chains

Good reads:
   - https://www.jackfranklin.co.uk/blog/context-in-reactjs-applications/

Note - if you see stuff with "childContextTypes" in it, it is the LEGACY API!

Take care
---------
Although the docs say that "Context is designed to share data that can be considered 'global' for
a tree of React components ...", note that the 'global' data being shared is relatively STATIC,
generally, as far as the child component is concerned - it won't update that data and cannot decide
whether it should render based on changes in the context. This is why, for example, lifecyle
methods haven't been expanded to see the previous context in the same way that one can see the
previous props in functions like shouldComponenetUpdate() - i.e., the context doesn't appear to be
designed to hold volatile state - obvs it might not be totally static, but just be aware. It's also
NOT A GREAT WAY TO RESOLVE PROP DRILLING, for the same reson: when deciding when to re-render the
context consumer cannot see the prevous context.

The docs have this to say:

    "If you only want to avoid passing some props through many levels, component composition is
     often a simpler solution than context."

VERY MUCH WORTH TAKING NOTE OF https://reactjs.org/docs/context.html#before-you-use-context


Class Based Components
-----------------------

Prop chains are where a prop is passed down from component A to grand-...-grand-child component X
via all the intermediate children, some or all of which may not care about the prop.

React offers "contexts" to help tidy what might be a messy load of prop chains.

You can create a context module. The course example is an authentication context. It is created
in a folder named "context" in a file named "AuthContext".
	import React from 'react';

	// The context is like a globally available JS object, just hidden inside the react "scope".
	// const authContext = React.createContext(...default-init-value...)
	//                                           ^^^^^^^^^^^^^^^^^^
	//                                           Normally an object but can be a number, string etc

	const authContext = React.createContext({
		authenticated: false,  // Default values dont really matter, but makes IDE auto complete better
		login: () => {}
	});

	export default authContext;


So, now in your application or the most parentish component that will "own" the context:

	import 'AuthContext' from '../context/auth-context';
	// AuthContext is used as a component that MUST WRAP ALL COMPONENTS THAT REQUIRED ACCESS TO IT.

	class App extends Component {

		render() {
			return
				<!--
				 -- NOTE here the AuthContext.Provider takes a value prop. That is why the defaults, generally,
				 -- dont matter.            Outer curlies to enter dynamic content
				                            v
				                            vInner curlies define the JS object
				                            vv  -->
				<AuthContext.Provider value={{authenticated: this.state.authenticated}}>
					<div>
						... All components that need access to the auth context ...
					</div>
				</AuthContext.Provider>;
		}
	}

NOTE how the state is still managed by, in this case, the App component, not in the Authentication
context. The reason for this is that React will only update when a state or prop changes, therefore,
updating it in the context object would _not_ cause a re-render. Hence it is managed and updated
by the app and just passed as a value to the context object.


Then in components that want to use the authentication context we do the following. These components
can be anywhere in the component hierachy and thats how we skip having to pass down props in trains.

	import AuthContext from '../../context/auth-context';

	class SomeComponent extends Component {
		render() {
			return
				<AuthContext.Consumer>
				<!--  Return a function which the AuthContext can then call with the context as
				      a parameter to said function.
				      vvvvvvv
				-->
					{(context) => {
						return ... your componenet code ...;
					}}
				<!-- ^^^^
				     You dont have to wrap every component. You could wrap a subset of the
				     components rendered if only they need the context -->
				</AuthContext.Consumer>
		}
	}

The AuthContext.Consumer is quite clunky and only gives you access to the context in the JSX code
and nowhere else. The alternative for class based components is this (React >= 16.6):

	class SomeComponent extends Component {
		static contextType = AuthContext;
		//^^^  ^^^^
		//^^^  Must be spelt exactly like this!
		//Must be a static property
		//
		// Allows React to connect your component with this context behind the scenes

		componentDidMount() {
			this.context.login; //< Access the context with "this.context" which ReactJS creates for us
		}

		render() {
			return .. your JSX code {this.context.login ? <p>Logged in</p> : <p>Log in</p> } ...
			//                       ^^^^^^^^^^^^
			//                       Can access it here too, without the wrapping consumer element.
		}
	}

Functional Based Componenets
----------------------------
React hooks can do the same thing for us. Import the "useContext" hook.

PropTypes For Contexts
----------------------
See the PropTypes section for an example of how this can be done. It seems okay but if the context
is dynamic it is still hard to test it on a per-component basis.



Planning A React Up

Steps:
  1. Component Tree / Component structure
  2. Application State (data)
  3. Components vs Containers
        Recall: components are "dumb" - just presentational and containers are statefull. Advise
        separate high-level directories for componenets and containers with subdirectories for
        each component/container.
        Recall: component/container subfolders with a Capital first letter.



Http & Ajax

Fake online REST API for Testing and Prototyping: https://jsonplaceholder.typicode.com/

	XMLHttpRequestObject
	--------------------
	Oldest and best supported but I'm gonna ignore it. If browser doesn' support newer Fetch API I
	assume Axios is the best drop in replacement.

	FETCH
	-----
	This is the newer version of XMLHttpRequestObject that is much easier to use and works with
	promises and asynchronous functions:
	    fetch(URL).next( result => {
	        console.log(result);
	        return result.json(); // Returns a promise that should resolve to the JS object created
	                              // from the JSON string returned by the API.
	    }).next( jsonObj => {
	        // Do something with the returned data which is now represented as a JS object for us.
	    }).catch ( error => {
	        console.log(`It failed due to ${error}`);
	    });
	
	Or... use await:
	    async function load_pr_stuff() {
	        const result = await fetch(URL);
	        const data = await result.json();
	        return data; // < Returns a promise!
	    }

	    load_pr_stuff.then( data => console.log("The final data is " + data) );
	    // ^^^
	    // Remember this is the way to get the final promise returned by the async function

	Given the workflow of CreateReactApp, the JS should be transliterated into JS that is also
	compatible with older browsers - I hope!

	AXIOS
	-----
	3rd party JavaScript library promise based HTTP client
	Given the workflow of CreateReactApp, the Axios JS will be transliterated into JS that is also
	compatible with older browsers! Happy days!

		npm install axios --save
		                  ^^^^^^
		                  Makes it store an entry in the package.json file

		In a new component file "my-first-axios.js":
			import axios from 'axios';
	
			const instance = axios.create({
				baseURL: 'https://my/api/end/point/base/address'
			});

		In existing component that wants to use AJAX:
			import axios from '../path/to/my-first-axios';
			...
			
			some_handler = () => {
				... probably set some "I am loading state" ...
				axios.post(
					'/endpoint relative to baseURL',
					javascript-object-repr-json					
				).then( response => {
					... probably cancel "I am loading state" and update some components ...
				}).catch( error => {
					... probably cancel "I am loading state" and update some components ...
				});
			}

		Handle GET requests similarly using axios.get().


    REST Generally
    --------------
    resource - nouns - separate API into resources
    resource based URLS
    HTTP methods are the verbs that act on resources
    SATELESS
    /addNewTour --> POST /tours
    /getTour    --> GET /tours/7
    /updateTour --> PUT /touts/7
                    PATCH /touts/7
    /deleteTour --> DELETE /touts/7



Multi Page In Single Page App (Routing)

React core does not implement routing. A third party defacto-standary package called react-router
is can be used.

Routing - show different pages to user based on path in URL. User JS to render different pages based
          on which path the user has navigated to.

Router package helps parse the path to figure out where user wants to go to. We then link these up
to where we want to point the user.

Server side, the same file is returned no matter what the path is - so has to be setup to do this.
The paths are only significant on the CLIENT SIDE.

INSTALLATION:
	npm install --save react-router react-router-dom

	Technically, only react-router-dom  is required for web development. It wraps react-router
	and therefore uses it as a dependency.

ENABLE:
	Do in index.js or App.js. In App.js wrap the App div inside "BrowserRouter". All children of
	the <BrowserRouter> tag will be able to access its routing functionalities:

		import React, {Component} from 'react';
		import {BrowserRouter, Route, Link} from 'react-router-dom'; // << INCLUDE THIS

		class App extends Component {
			render() {
				return (
					<BrowserRouter                      <!-- << USE IT LIKE THIS -->
						[basename="/first-app"]     <!-- << If served from server.com/first-app, otherwise optional -->
					>
						<div className="App">
							<!-- The app contents -->
						</div>
					</BrowserRouter>
				);
			}
		}

USE:
	In components/containers:

		Render small things
		-------------------
		import {Route} from 'react-router-dom';

		...
			render() {
				<!-- Note how Route tag is self closing -->
				<Route
					path="path for which this path should become active"
					render={some function to render for this path}
				/>

				<!-- For example: -->
				<Route
					path="/"
					exact   <!-- << NOTE means final slash is necessary to match - means "is my
					                complete path like this?" vs "does my path start with this?" -->
					render={() => <div>A test</div>}
				/> 

				<!-- Route more-or-less replaces itself with the content defined in render.
				     You can even use multiple route's for the same path -->
			}


		Render components
		-----------------
		But if you want to RENDER A COMPONENT,  use the component property like so:
			<Route
				path="..."
				[exact]
				component={Ref to function or class to use}
			/>

		I think in router v6 (https://stackoverflow.com/a/70008235) it needs to be a JSX
		element.
			<Route path="..." component={<MyElement/>} />

		Also in v6 activeClassName also no longer works: https://stackoverflow.com/a/70008545

		SEE: https://reactrouter.com/docs/en/v6

	Prevent reloads on link navigation:
	-----------------------------------
		Reloading a page KILLS THE CURRENT APP STATE!! WE DO NOT WANT THIS

		To prevent links always re-rendering pages, i.e., reloading them, the links must be changed
		to look like this:

		Don't use <a>, use <Link>!
		The <a> tag...
			<a href="...">...</a>
		... is replaced with a <Link> tag:
			<Link to="...">...</Link>
		... or, more completely but with more complexity:
			<Link to={{
			   pathname: '/something' <!-- NOTE: This is always treated as an ABSOLUTE path... -->
			   hash:     '#something' <!-- ...wether or not it has a prefix of '/' -->
			   search:   '?arg=param'
			}}>...</Link>

		This allows react to intercept the link click and instead of the page being loaded from
		fresh, it can just render what changes are needed WITHOUT having to reload the page.

		Note that the link pathname is always treated as an absolute path, so if you want to use
		a relative path you have to build it up into an absolute one by using the page you are 
		currently on, given by "this.props.match.url", and appending the target:
			e.g., pathname: this.props.match.url + "/relative/path";

		If you want to add some styling to the active and non-active links it is bettery to use
		<NavLink>. This adds an "active" class to the active link for you. Note there can be
		many "active" links if more than one Link path matches. The reason for this is that the
		link path is TREATED AS A PREFIX (just like in Router). So to match exact use the exact
		attribute.

			<NavLink to={{
			   pathname: '/something'        <!-- << This is always treated as an ABSOLUTE ... -->
			   [exact]                       <!-- ... path whether or not it has a prefix of '/' -->
			   [activeClassName="my_active"] <!-- << Override the default active classname -->
			   [activeStyle={{...}}]         <!-- << Dynamically specify style for active -->
			   hash:     '#something'
			   search:   '?arg=param'
			}}>...</Link>



	Extra Props We Get From React Router
	------------------------------------

	Components rendered via a <Route> get some extra attributes that are automatically added
	to "props" for us.
		1. history
		2. location
		3. match
	HOWEVER, these props ARE NOT PASSED DOWN THE COMPONENT TREE. To pass these down one would have
	to explicity pass them down to a child using {...this.props} as an attribute to a child node
	from the parent node that is being displayed because of a <Route>.

	Another way is to use the HOC withRouter. Use it to wrap the child components you want to have
	access to the <Route> attributes:
		import { withRouter } from 'react-router-dom';
		...
		export default withRouter(my_component);


	Routing Parameters
	------------------

	If we want to visit links such as "/1", /2" etc routing parameters are rquired:
		<Route path="/something" /> <!-- << NOTE that routes are used in the order they are defined
		                                    to, "/something" will match before :id, but rember
		                                    ALL ROUTES ARE RENDERED IF THEY MATCH THE PATH  -->
		<Route
		   path="/:id"
		   exact 
		   component={...}/>

	To pass route parameters via our links just do something like
		<Link to={'/path/' + this.props.id}> ... child elements or text ... </Link>

	Can restrict values of :id using https://stackoverflow.com/a/54113392:
		{/* It's possible to use regular expressions to control what param values should be matched.
		  * "/order/asc"  - matched
		  * "/order/desc" - matched
		  * "/order/foo"  - not matched*/}
		<Route
			path="/blah/:id(asc|desc)"
			component={ComponentWithRegex}
		/>
		-- anything https://github.com/pillarjs/path-to-regexp/tree/v1.7.0 can understand!!
	But, apparently v5 supports this but v6 does not - see the discussion in their faq
	here - https://reactrouter.com/docs/en/v6/getting-started/faq#what-happened-to-regexp-routes-paths

	To get the value of "id" in the component we need to access the magic props attributes that
	Router added for us:
		match.params['id'] // It is called "id" as that was the name in the Route:path definition
	Can also use
		match.params.id

	Remember the ALL the Routes that match the path will be rendered. If you want only ONE match
	to be rendered (the one that is seen first btw), the use <Switch> to wrap the <Route> tags:
		<Switch>
			<Route .../>
			...
			<Route .../>
		</Switch>


	Search Parameters
	-----------------
	These are not the route parameters which come from that _path_ in the URL. These are the 
	query parameters that occur at the end of the URL after a "?". For example:
		www.jeh-tech/my_page?my_value=123

	Pass in links using
		<Link to="www.jeh-tech/my_page?my_value=123"/>
	Or
		<link to="www.jeh-tech/my_page" search="?my_value=123"/>

	Can the access using
		props.location.search

	To parse search string easily use:
		const query = new URLSearchParams(this.props.location.search);
		for (let param of query.entries()) {
			console.log(param);
		}

	URLSearchParams  is a built-in object, shipping with vanilla JavaScript


	Natigating Programatically
	--------------------------
	To navigate to a page:
		props.history.push({pathname: "/my/link/path"});
	or 	props.history.push("/my/link/path");


	Nested Routing
	--------------
	Load a component inside another component which is also loaded via routing - you can use the
	<Route> component wherever you want, as long as the page is a child, grandchild etc of the
	<BrowserRouter> component.

	WARNING: that nested <Route>s do not resolve relative to their parent route. For example, if
	the parent was "/pull-requests" and the URL was "/pull-requests/1/" and the child route is
	"/:id", this does not resolve to "/pull-requests/:id"!

	To solve this in nested routes, get the current path DYNAMICALLY:
		<Route path={this.props.match.url + '/:id'} />

	WARNING: React router does not always _replace_ the component so it won't always re-render the
	component. The lifecycle hook componentDidMount() won't get called. But what will be called is
	componentDidUpdate() so this will also need to be implemented. But be careful - the decision
	as to wether to re-render must avoid infinite loops!


	Redirecting Requests
	--------------------
	Rather than having multiple paths to render the same content, you can use special Redirect
	component from react-router-dom:
		<Switch>
			...
			<Redirect from="/" to="/pull-requests"/> <!-- Can only use "from" inside a Switch -->
		</Switch>

	Redirect doesn't render content - it redirects the URL which can then be caught by another
	route and then rendered by the actual route. So as soon as it is "rendered" the page URL will
	be changed, regardless of any other components that would otherwise have been rendered after it.
	E.g.,
		<Redirect to="/pull-requests"/> <!-- No "from" allowed outside of a <Switch> -->
		<p>Some text</p>                <!-- Will not be rendered because of redirect -->

	Such redirects can be used conditionally using normal JS. E.g.:
		const redirect = some-condition ? <Redirect to="..."/> : null;
		<div>
			{redirect}
			... some content ...
			}
		</div>

	Sometimes, if you want to push a new page onto the history stack (redirect _replaces_ the top
	of the stack) to maintain navigability use `props.history.push(url)` instead.


	Guards
	------
	Ways to stop pages being navigated to if they should not be accessilbe - e.g. because they
	require the user to have authenticated (logged in).

	Just use Javascript!
		{this.state.auth ? <Route ... /> : null}
		                                   ^^^^^
		                                   If definition isn't rendered then this route does not
		                                   exist.


	Handle Unknown Routs - 404
	--------------------------
	Make the _last_ Route in your Switch
		<Route render={() => <h1>Not Found</h1>} />


	Lazy Loading
	------------
	NOTE: requires react-router >= 4 & create-react-app (Webpack config required)

	For big apps don't want to down load *all* the app code... only code that will be needed. So,
	for pages etc that are seldomly likely to be visited or components seldomly used, we only want
	to download their code on demand, not "up front".  loading, a.k.a "code splitting", is the way
	to address this.

	To do this you need to create a HOC "asyncComponent" - left this for now... come back to it if
	I ever need it.

	BUT - if React >= 16.6 you can use React Suspense to do this for you :D React Suspense adds a
	new method to the Component object that you can use to do lazy loading!



Form Validation

For inputs when adding an "onChange" event handler remember two way binding! You have to modify
your state so that the changes made will be rendered.

The submit button does not need to have its "onClick" property used. The form JSX tag has an
"onSubmit" property which can be used to supply a validator function reference that guards
form submission. This is part of the basic functionality of forms in HTML

In submission event handler remember to use
	event.preventDefault();
IMPORTANT - Use event.preventDefault() otherwise form submission reloads the page! This is the
default form behavior.

submitHandler = (event) => {
	event.preventDefault();
}

<form onSubmit={submitHandler}>
</form>

There are two ways to validate the form. At the end, when the form is submitted, or whilst values
in the form elements change.

To validate on final submission one way is to useRef()

    const myFormThing = (props) => {
        const myEl = useRef();
        ...
        const myhandler = (event) => {
            event.preventDefault();
            const elData = myEl.current.value; //< Use of REF
            ...
        }
        ...
        <form onSubmit={myhandler}>
            ...
            <input ref={myEl} .../>
            ...
        </form>
    }

However, if you intend to set the value of any of the inputs then classic setState style and not
refs will be preferable as to manipulate the DOM you should really use state and not modify refs
directly. React should be the only thing manipulate the DOM!

When validating on the fly the usual onChange etc two way binding can be used. onBlur() and
on key press can also be used in combination to set errors when an input looses focus and to
clear the error as soon as it is rectified.

Useful **custom hook** pattern:

import {useState } from'react';

const useInput = (validateValue) => {
	const [enteredValue, setEnteredValue] = useState('');
	const [isTouched, setisTouched] = useState(false);

	const valueIsValid = validateValue(enteredValue);
	const hasError = isTouched && !valueIsValid;

	const valueChangeHandler = (event) => {
		setEnteredValue(event.target.value);
	}

	const inputBlurHandler = (event) => {
		setIsTouched(true);
	}

	const reset = () => {
		setEnteredValue('');
		setIsTouched(false);
	}

	return {
		value: enteredValue,
		hasError,
		valueChangeHandler,
		inputBlurHandler,
		reset
	}
};


This can then be used in the form component:
const myForm = (props) => {
	const {
		value: value1,
		hasError: hasError1,
		valueChangedHandler: valueChangeHandler1,
		inputBlurHandler: inputBlurHandler1
	} = useInput((value) => some-predicate);

	...

	return (
		<form>
			<input onChange={valueChangeHandler1} onBlur={valueBlurHandler1} value={value1}/>
		</form>
	);
}

Redux

See: https://redux.js.org/introduction/getting-started
     https://redux.js.org/introduction/core-concepts
     https://redux.js.org/basics/actions
     https://redux.js.org/basics/reducers
		 https://redux.js.org/advanced/middleware/
		 https://github.com/gaearon/redux-thunk
		 https://redux.js.org/advanced/async-actions

Redux - 3rd party library. Most often associated with React but not part of React. It is independent.

One of the benefits of Redux is that it makes state changes predictable and transparent. Every time
an action is dispatched, the new state is computed and saved. The state cannot change by itself,
it can only change as a consequence of a specific action.
  -- From redux online docs

It provides a _clearly defined process_ on how the _state in some central store_ can change. It provides
a GLOBAL STATE across the entire app, that ALL components/containers can access in a well defined
way.

Why not just globals: From this post (https://www.reddit.com/r/reactjs/comments/b4p87h/redux_is_just_money_laundering_for_global/):
	It's important to remember why we consider global variables bad: because anything can change
	them at any time and you won't know why during debugging ... Redux solves the visibility problem
	really well by introducing an event driven paradigm to state.
	...
	...
	the restriction of sending typed actions and then doing work explicitly designed with reducers
	(instead of having business logic scattered all over the place inside components)
	...
	...
	Use redux for what's really global and for every thing else I would keep state as close as
	possible to where they are used.

Why not just global, from this post (https://news.ycombinator.com/item?id=13332914)
	Lots of reasons:
	- Isolation of "write logic" means you know where to look to see what code is updating a given
	  chunk of state
	- Consistent state handling means it's a lot easier to think about what's going on in the
	  application
	- The DevTools show you a log of dispatched actions, and enable you to step back and forth
	  between states to see what the UI looked like at each point
	- Middleware lets you centralize app-wide logic, such as consistent transformations for AJAX
	  responses
	- Redux's constraints (such as wanting state to be serializable) enable a number of other use
	  cases, such as persisting state across page reloads and synchronizing multiple stores remotely.
	- There's a rapidly growing ecosystem of addons and utilities for specific use cases
	  (see https://github.com/markerikson/redux-ecosystem-links )
	-  I use time-travel debugging on a daily basis, and it's a _huge_ time-saver for me.


                                    +---> Reducer -----+
                                    :                  :
                                    :                  :
                                    +---> Reducer -----+-----> ROOT reducer
                                    |                  |           |
  Action ------> MiddleWare --------+---> Reducer------+           |
    ^                                                              |
    |                                                              | [Updates]
    | [Dispatches]                                                 |
    |                                                              v
Component                                                    Central Store
    ^                                                              |
    | [Passes updated state]                                       | [Triggers]
    |                                                              |
    +------------ Subscription <------------------------------------+


Redux provides a central store, which is the ENTIRE APPLICATION STATE. Most often this will be things
like the authenticated state of the user, for example.

Actions are a way for a component to tell Redux "I'd like to change the state... here is the plan on
how to do that". They are just a pre-defined informational package, optional payload, that tells
Redux about the plan. This is the PUBLISH a.k.a DISPATCHING AN ACTION.

Reducers receive actions and handle the update of the central store. THe reducers must be completley
SYNCHRONOUS ans have NO SIDE EFFECTS. If there are multiple reducers, they are, in the end, merged
into one single reducer, which is what gets to modify the central store.

Once the central store is updated it informs all its SUBSCRIBERS of the state change, passing
the updated state, as props, to its subscribers.

Install Redux in the usual manner:
	npm install --save redux


REDUCER:
	Gets: State, Action.
	Returns: Updated state. But original state must NOT be mutated! Just like it setState() func.
	         NEVER mutate any data!

		const rootReducer = (surrentState = intialSate, action) => {
			//                              ^^^^^^^^^^^^
			//                              Useful because when reducer created it wont be passed a state
			if (action.type == ...) {
				... do something for this type
			}
			else if (action.type == ...) {
				...
			}
			// and so on...

			return new_state; // new_state must COPY from state. state must NOT be mutated
		}

STORE:
	Created with a root reducer.
		createStore = redux.createStore;
		const store = createStore(rootReducer);
		let currentState = store.getState();

ACTION:
	Just access store and call dispatch(). Func takes action as arg - a JS object that MUST have
	a "type" property so that we know what type of action was dispatched and what should be done in
	the reducer.

		store.dispatch({
			type: 'CONVENTION_IS_SHORT_UPPER_CASE_DESCRIPTION'
			value-name-of-choice: value-data,
			more-values: more-data,
			...
			...
		});

SUBSCRIPTION:
	Inform us when something changed and we need to re-get the state.
	Use: store.subscribe(function-executed-whenever-state-updates);

		store.subscribe( () => { // Subscribe func gets NO args
			... store.getState(); ...
		});



Using Redux With React
----------------------
Must install react-redux to "hook up" redux stores to react application:
	npm install --save react-redux

The Redux store should be created before or when our App or when it starts - use `index.js`!

	import { createStore } from 'redux';
	import { Provider } from 'react-redux'; //NOTE:  Must WRAP the app with <Provider>

	import reducer from './store/reducer'; // Generally may have many complex Reducers
	                                       // so these will be stored in their own files in their
	                                       // own folders in our app. Perhaps a "store" folder next
	                                       // to the containers and components files.

	const store = createStore(reducer); // Define in separate file, reducer.js

	// NOTE: Must WRAP the app with <Provider>
	ReactDOM.render(<Provider store={store}><App /></Provider>, ...);
	//              ^^^^^^^^^^^^^^^^^^^^^^^
	//              Wrap app with Provider, which provids our store. "injects" our store into the
	//              reactor components in the app.

	registerServiceWorker();


In reducer.js
- - - - - - -
	const initialSate = {
		...
	};

	const reducer = (state = inialState, action) => {
		// your actions here or just return state if nothing should change.
		if (action == 'ACTION_TYPE')
		{
			return {
				// Immutably created new state
			};
		}
		...
		...
		return state; // LAST RETURN handles unrecognised actions and returns state unchanged.

		// Or use switch (action.type) { case 'BLAH': break/return; ... default: return state; }
	};

	export default reducer;

In the reducer you can replace the if-else blocks with a switch statement:
   switch(action.type) {
      case 'SOME_TYPE_1':
         return {
            new_state_member: new_value,
            ...
         }
      case 'SOME_TYPE_2::
         return { ... }
      ...
   }

WARNING WARNING WARNING: The state returned from the reducer is, unlike in react, NOT merged with
the existing state. It just becomes the state. This means YOU HAVE TO DO THE MERGE YOURSELF by
DEEP copying th existing state (current state is IMMUTABLE) and modifying the copy as appropriate.


In components that required access to the store:
- - - - - - - - - - - - - - - - - - - - - - - - -
	import { connect } from 'react-redux';

	class MyComponent ... {
		...
		render() {
			...
			<!-- Here can access redux state mapped to our props as defined below -->
			<eg_element clicked={this.props.onSomeEvent}>{this.props.a_props_attribute}</eg_element>
			//                        ^^^^^ ^^^^^^^^^^^              ^^^^^^^^^^^^^^^^^
			//                        ^^^^^  ^^^^^^^^^^^              From mapStateToProps
			//                        ^^^^^ From mapDispatchToProps
			//                        ^^^^^
			//                        NOTE HOW WHAT WAS THE STATE IS NOW ACCESSED AS PROPS!
			...
		}
	}

	// How state, managed by redux, should be mapped to props that can be accessed in this component
	// The state parameter is the state as setup in reducedr.js so it will have those propertues.
	const mapStateToProps = state => { // Func that expects the state, stored in redux and returns a map
		return {
			a_props_attribute: state.some_state_var
			//                 ^^^^^
			//                 The state passed into the function which is the state provided by redux!
			...
			...
		};
	}

	// Which actions the container will DISPATCH
	const mapDispatchToProps = dispatch => {
		return {
			onSomeEvent: (param1) => dispatch({type: 'ACTION_TYPE', actionParam1: param1, ...}),
			...
		};
	};

	// `connect` returns a new function that accepts the component to wrap:
	// Either
	export default connect(mapStateToProps)(MyComponent); // Connect is func that _returns_ a HOC

	// Or
	export default connect(mapStateToProps, mapDispatchToProps)(MyComponent); // Connect is func that _returns_ a HOC


Updating state IMMUTABLY
------------------------

The state object passed into a reducer MUST NOT BE MODIFIED.
So doing the following is WRONG
	let newState = state;
	newState.something += 101; // WARNING - just MUTATED the state!
	return newState;

Instead MUST COPY THEN MODIFY COPY of state:
	let newState = Object.assign({}, state); // SHALLOW clones object
OR
	let newState = {...state, something: state.something + 101 }; // Still a SHALLOW clone!

CAUTION: With SHALLOW copies you cannot update any reference types in the copy.

SEE SEE SEE: https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns/



Updating Arrays IMMUTABLY
-------------------------
I was doing it by deep copying the array with object and then doing a splice().

Another method is to use the Array.filter() method as filter returns a NEW array.

Eg, to delete a particular index in an array in a react state, as we need to copy the array before
modifying it, rather than doing it manually, can do it using filter:

newArrayWithDeletedItem = state.member.filter(
	(arrayItem, itemIndexInArray) => itemIndexInArray != itemIndexToDelete
);

SEE SEE SEE: https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns/



Using Mulltiple Reducers
------------------------
In `index.js`:

   ...
	 import { createStore, combineReducers } from 'redux';
	 //                    ^^^^^^^^^^^^^^^
	 //                    Need this extra new import; Combines the state all all sub-reducers into
	 //                    ONE state... therefore sub-reducers can still access state from other
	 //                    subreducers, as there is really only one root reducers with the one state
	 //                    that combines the sub-states of all the sub-reducers.
   ...
   import myFirstReducer from '...';
	 import mySecondReducer from '...';
	 ...
	 ...
	 // Construct the root reducer
	 const rootReducer = combineReducers({
	    appAreaName1 : myFirstReducer,
	    appAreaName2 : mySecondReducer,
	  // ^^^^^^^^^^^
		// There names gives us access to the substates in our app. In our app, to access these sub states
		// must do const
		// mapStateToProps = state => {
		//     return {
		//     	a_props_attribute: state.appAreaName1.some_state_var
		//                               ^^^^^^^^^^^^
		//                               NOTE extra layer of nesting in state
		//     	...
		//     };
	  // }
	    ...
	 });
	 const store = createStore(rootReducer);
	 //                        ^^^^^^^^^^^
	 //                        NOTE: Now the ROOT reducer is passed in as in Redux there is really
	 //                              only ONE reducer.
   ...
	 ReactDOM.render(<Provider store={store}><App/></Provider>);

BUT WARNING WARNING WARNING
	The sub-reducers can NO LONGER ACCESS THE GLOBAL REDUCER STATE!!! They cannot "see" the state
	in the other sub-reducers. Thus, if they need state from another reducer they SHOULD RECEIVE IT
	AS PART OF THE ACTION PAYLOAD INSTEAD.



You CAN MIX Redux With Local React State
----------------------------------------
You CAN use redux and still have local state in component and use reacts.setState(). For example,
local UI state, like whether a modal should be displayed etc, is usually more appropriately stored
as local state and NOT in redux.

Local state, can then be passed to Redux actions if they are required by other parts of the app.



Middleware
----------
SEE: https://redux.js.org/advanced/middleware
		Middlware provides a third-party extension point between dispatching an action, and the moment
		it reaches the reducer.

// This whole set of nested functions (function tree) IS a middleware!
//             Redux will call this middleware function and pass it the store!
//             vvvvv
const myMiddleWare = store => {
   // Middleware function returns a function. This function lets the action continue on its
   // journey to a reducer. This function will also, eventualy, be executed by redux.
   return next => {
     // Return yet another function that received the action that was dispatched as its parameter
     return action => {
       // Here can access store, next and action. This code is run inbetween the action and the
       // reducer.
       const result = next(action); //<<< Lets action continue to the reducer
       ...
       return result;
     };
   };
};

To use the middleware must import applyMiddleware from Redux:

		import { createStore, combineReducers, applyMiddleware } from 'redux';
		//                                     ^^^^^^^^^^^^^^^

		...

		const store = createStore(rootReducer, applyMiddleware(myMiddleWare, ...));
		//                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		//                                     NEW second argument here applys an "enhancer" to the
		//                                     store, which in this case is our middleware.
		//                                     The function applyMiddleware accepts a list of middlewares
		//                                     that will get executed in order.



Redux DevTools
---------------
Help debug the store!



Asynchronous Code and Redux Using Redux-Thunk
---------------------------------------------

RECALL: REDUCERS CAN **NOT** RUN ASYNCHRONOUS CODE! This is because the reducer returns immediately,
so what ever state modification are dependent on the async code can't be comminucated back to react
via this reducer - the reducer would finish before the async result was ready!

USE ACTION CREATORS to overcome this problem. Action creators can be good for both sync and async
code. For sync code they make the action object creation centralised into one function that accepts
arguments rather than having the action object potentially created in many places.

eg:
  // This is a SYNC action creator
	export const MY_ACTION = "MY_ACTION";
	export const myAction = (payload) => {
		return {
			type: MY_ACTION,
			payload: payload,
			...
		};
	};

	// And we use it in our Redux compoent's mapDispatchToProps like so.
	const mapDispatchToProps = dispatch => {
		return {
			// onSomeEvent is NO LONGER LIKE BELOW
			// onSomeEvent: (param1) => dispatch({type: 'ACTION_TYPE', actionParam1: param1, ...}),
			//
			// It is now written like
			onSomeEvent: (param1) => dispatch(myAction()),
			//                                ^^^^^^^^^^
			//                                Action creator function returns, synchronously, the action
			//                                rather than creating the object in each instance the
			//                                action is created - more DRY!
			...
		};
	};

Thunk allows the action creators to, instead of returning an action object, return a function that
will eventually dispatch an action. The "eventually dispatch" means that this ENABLE ASNC CODE.

DO:
	npm install --save redux-thunk

In your app you now add:

	import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
	// NEW vvvvv
	import thunk from 'redux-thunk';

	...

	const store = createStore(rootReducer, applyMiddleware(myMiddleWare, thunk));
	//                                                                   ^^^^^
	//                   Thunk added to the list of middleware added to our app's store.


Then create the ASYNC action creator as follows:
In action creaters, no longer return action, but RETURN A FUNCTION that will EVENTUALLY DISPATCHING AN ACTION!

Eg, with the myAction action creator from above:

	export const myAction = (payload) => {
		return {
			type: MY_ACTION,
			payload: payload,
			...
		};
	};

BECOMES

	export const myActionSync = (payload) => {
		return {
			type: MY_ACTION,
			payload: payload,
			...
		};
	};

	export const myActionAsync = (payload) => {
		//                         Can pass getState - but it is optional... we don't have to use it.
		//                         It can be called to retrieve the current state, if we need to use it.
		//                         This is the state PRIOR to us re-dispatching the action.
		//                         vvvvvvvv
		return function(dispatch[, getState]) {
			setTimeout( () => {
				dispatch(myActionSync(payload))
				//       ^^^^^^^^^^^^
				//       NOTE must call sync action, not async version, otherwise create infinite loop!
			}, 2000);
		};
	};

This works because in our React component we have:
	const mapDispatchToProps = dispatch => {
		return {
			onSomeEvent: (param1) => dispatch(myActionAsync()),
			//                               ^^^^^^^^^^^^^^
			//                               NOTE action creator is not the async version...
			...

Because the action creator now returns a function, the thunk middleware detects this when the
action is dispatched and DELAYS the action, by calling our function, through which we can do
something asynchronously, and then call the real, non-delayed, Redux dispatch method, which will
make it to the reducer, when we are ready.



Data transformations
--------------------
Action reducers are FREE TO MODIFY AND ADD ANY DATA TO THE ACTION PAYLOAD:

	export const myActionSync = (payload) => {
			const newPayload = someTransform(payload);
			return {
				type: MY_ACTION,
				payload: newPayload,
				...
			};
		};

You can also do this in the reducer itself. Better to do in action as its more flexible - different
transformations for different actions that modify the same data item in the store. (my opinion)

Remember: Reducers run SYNCHRONOUS CODE only, but part of core redux,
          Action creators CAN RUN AYSCHONOUS CODE as well as synchronous code, require thunk add on.


Some utility functions:
-----------------------
const updateObject = (oldObject, updatedValues) => {
	return {
		...oldObject,
		...updateValues
	};
};



Authentication

Typically, rather than a session, get a TOKEN, in a SPA as the server is generally a stateless
REST API. Token is stored in local browser storage.

User local browser storage:
	localStorage.getItem("string key")
	localStorage.setItem("string key", "sting value")

Not browser local storage is not super secure. It could be accessed using XSS attacks, but otherwise
should only be accessable by code served in your domain (single origin policy).



Testing

Could use Selenium but can also use NodeJS packages which will simulate the browser, which could
make for faster unit tests.

Jest - Populare JS testing tool often used with ReactJS

Also need a way of emulating React components without having to render an entire DOM. We still need
some kind of fake DOM but don't want everything. React Test Utils can do this, or use Enzyme as
developed by Air Bnb - also recommended by React team.

	npm install --save enzyme react-test-renderer enzyme-adapter-react-16
	                                              ^^^^^^^^^^^^^^^^^^^^^^^
	                                              This one has to be specific to your react version

See: https://jestjs.io/docs/en/expect
     https://jestjs.io/docs/en/jest-object#mock-modules << Good for mocking AJAX calls for e.g.
     https://enzymejs.github.io/enzyme/

When naming a test for a component, put it in the same directory as the component. If the component
file name is MyComp.js then the TEST MUST BE NAMED MyComp.test.js, as this will then be
AUTOMATICALLY picked up and included in the testing.

To run the tests just use
	npm run test

Enzyme vs React Test Utils vs react-testing-library
--------------------------------------------------
	FROM https://stackoverflow.com/a/54152893/1517244:
	ReactTestUtils gives you the bare minimum to test a React component. I haven't seen it being
	used for big applications.

	Enzyme and react-testing-library are both good libraries that give you all the tools you need to
	test your application. They have two different philosophies though.

	Enzyme allows you to access the internal workings of your components. You can read and set the
	state, and you can mock children to make tests run faster.

	On the other hand, react-testing-library doesn't give you any access to the implementation
	details. It renders the components and provides utility methods to interact with them. The idea
	is that you should communicate with your application in the same way a user would. So rather than
	set the state of a component you reproduce the actions a user would do to reach that state.

	In my experience Enzyme is easier to grasp but in the long run, it's harder to maintain.
	react-testing-library forces you to write tests that are a bit more complex on average but it
	rewards you with higher confidence in your code.

	FROM https://stackoverflow.com/a/54153026/1517244:
	Enzyme is intended for unit/integration testing. Its API was designed to test the implementation.
	It offers custom renderer that doesn't require DOM (for shallow rendering), behaves differently
	from React renderer and allows things that are important for unit testing but aren't possible or
	straightforward with default renderer, like synchronous state updates, shallow rendering,
	disabling lifecycle methods, etc.

	react-testing-library is intended for blackbox integration/e2e tests. It uses React renderer and
	ReactTestUtils internally, requires real DOM because it's component's output that is asserted in
	tests, not internals. It doesn't provide facilities for isolated unit tests but it's possible to
	do this by mocking modules that contain component that need to be spied, mocked or stubbed by
	other means, notably jest.mock.

	react-dom/test-utils and react-test-renderer contain a subset of functionality, Enzyme and
	react-testing-library were built upon them. API is scarce and requires to write boilerplate code
	or custom utility functions for full-grown testing. React officially promotes Enzyme and
	react-testing-library as better alternatives.


Testing Components
-----------------
	In the MyComp.test.js file you do not need to import the test specific libraries - they will be
	made available automatically by the test command.

		MyComp.test.js
		--------------
			import React from 'react';
			import { configure, shallow } from 'enzyme';
			//                  ^^^^^^^
			//                  Does a shallow rendering of the component under test - it will produce
			//                  kind-of "stubs" for the immediate children and thus PREVENTS rendering
			//                  an entire subtree - efficient!
			import Adapter from 'enzyme-adapter-react-16';
			import MyComp from './MyComp';
			imoprt OtherComp from '...';

			configure({adpater : new Adapter()}); // Connect Enzyme to our React version

			describe(
				'Description of thest bundle file holds - just str for console',
				() => {
					//
					// DEFINE setup and teardown for this group of tests
					beforeAll( () => { ... } );
					afterAll( () => { ... } );

					//
					//
					// DEFINE setup and teardown for each test
					//
					let wrapper;
					beforeEach( () => { wrapper =  shallow(<MyComp/>); } );
					afterEach( () => { ... } );

					//
					// DO each test
					//
					it(
						'Should ... describe on individual test - just str for console',
						() => {
							// Create instance of component as it would be rendered into the DOM, (without
							// creating the entire DOM!) and then inspect it. Enzyme allows component to
							// be "rendered" stand-alone, i.e., without rest of DOM.
							//
							// If wrapper wasn't defined in the setup for each test we'd do
							//   const wrapper = shallow(<MyComp/>);
							//
							// But it is so...

							expect(wrapper.find(OtherComp)).toHaveLength(2);
							//                  ^^^^^^^^^
							//                  Note this is the JS function, NOT JSX!

						}
					);

					it(
						'Should do something else when another property is set',
						() = {
							// If wrapper wasn't defined in the setup for each test we'd do
							//   const wrapper = shallow(<MyComp myAttr=Something/>);
							//
							// But it is so...

							wrapper.setProps({myAttr : Something});
							expect(wrapper.find(...))...();
						}
					);
				}
			)


Testing Containers
------------------



React Hooks (React >= 16.8)

Do not confuse with life-cycle hooks like didComponentMount() which are associaed soley with class
based components.

React hooks allow functional components to be used *everywhere*. React-hooks do for functional
components what state and the lifecycle hooks do for class based components. I.e., HOOKS REPLACE
CLASS-ONLY FUNCTIONALITY.
	- Add state
	- Share logic across components
	- Implement functional lifecycle-like functionality.
	- Can build custom hooks

React hooks are just JS functions that can only be used inside a functional component or other hooks
(you can write your own).

All hooks are called useXXX(). Eg useState() etc.

See https://reactjs.org/docs/hooks-intro.html for motivation for hooks. From that page:
		It’s hard to reuse stateful logic between components
		React doesn’t offer a way to "attach" reusable behavior to a component (for example, connecting
		it to a store). If you’ve worked with React for a while, you may be familiar with patterns like
		render props and higher-order components that try to solve this. But these patterns require you
		to restructure your components when you use them, which can be cumbersome and make code harder
		to follow. If you look at a typical React application in React DevTools, you will likely find a
		"wrapper hell" of components surrounded by layers of providers, consumers, higher-order
		components, render props, and other abstractions. While we could filter them out in DevTools,
		this points to a deeper underlying problem: React needs a better primitive for sharing stateful logic.

		With Hooks, you can extract stateful logic from a component so it can be tested independently and
		reused. Hooks allow you to reuse stateful logic without changing your component hierarchy.
		This makes it easy to share Hooks among many components or with the community.



Important Rules
===============
See: https://reactjs.org/docs/hooks-rules.html

RULE 1: Only Call Hooks at the Top Level
*** Don’t call Hooks inside loops, conditions, or nested functions. ***
Instead, always use Hooks at the top level of your React function. By following this rule, you
ensure that Hooks are called in the same order each time a component renders. That’s what allows
React to correctly preserve the state of Hooks between multiple useState and useEffect calls.
This is because React relies on the order in which Hooks are called to know which state corresponds
to which useState call

By "calling hook" it means the functions useState(), useEffect() etc. It does NOT refer to using
the state and state-setting-function they return! These can be used as per normal!

RULE 2: Only Call Hooks from React Functions
You can only call Hooks from React function components and from custom Hooks.


USE eslint-plugin-react-hooks to help you enforce these rules.
    npm install eslint-plugin-react-hooks --save-dev

Read also: https://stackoverflow.com/questions/53845595/wrong-react-hooks-behaviour-with-event-listener



useState()
==========
See: https://reactjs.org/docs/hooks-state.html

import React, { useState } from 'react';
...
const defaultState = ...; // Any value - unlike class state does not have to be an object
...
const MyFunctionalComponent = (props) => {
   // The state will survive re-renders
   // Returns an array with *2* elements
   // 0: the current state snapshot
   // 1:function to use to update the current state
   const [myState, mySetState] = useState(defaultState);
   ...
   // Use myState exactly as you would have used this.state in class component
   // Use mySetState like you would have used this.setState() in class component BUT WARNING, it
	 //   does NOT MERGE STATE FOR YOU!!!
   ...
   return (...);
};


WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
WARNING - useState's setState-like function DOES NOT MERGE STATE, IT **REPLACES** THE CURRENT
          STATE WITH THE ONE YOU GIVE IT!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

Just like setState(), the useState()'s update function accepts a function instead of an object when
you need to update state based on previous state, except that it obv doesn't receive any props.

e.g.
    onChange = {
        (event) => mySetState(
            (prevMyState) => (
                {newVal: prevMyState.val + X}
            )
        )
    }


WARNING - BE CAREFUL NOT TO CAPTURE PARAMETERS IN CLOSURE

    onChange = {
        (event) => mySetState(
            (prevMyState) => (
                {
                    something: event.target.value, // <<<< ERROR. See description below code.
                    newVal: prevMyState.val + X
                }
            )
        )
    }

Problem is this:
1. First onChange event fires and the onChange handler is called. It is passed a React synthetic
   event object, which is POOLED. The handler returns a function, which closes over the outer
   scope's environment, capturing the instance of event from the event pool. It is this inner function
	 that is the "problem" and creates the closure over the pooled synthetic event.
2. The second onChange event fires and executes the handler, passing in a different synthetic event
   object, which too gets captured in the closure created.
3. At some point React will deal with these events, but it can do so when it chooses. React may
   re-use the event object that we have closed over in a previous handler
	 that is yet to be called and when it is it will see the new event state, not the one it is
	 supposed to see. There is no way to "release" event Reacts synthetic event objects, so it has
	 no way to know if we are "holding" on to one in this way.

The solution is:
In the outer function, create const variables that copy the pertinant event data and use these in
the inner function. This way the event can be safely re-used by react.


Overcoming complexities of setting state
----------------------------------------
Remember that useState::setState function DOES NOT MERGE THE STATE OBJECT FOR YOU. Each time you
must set the ENTIRE state.

You can make life simpler by registering multiple state objects.
Just do
	const [state1, state1SetFunc] = useState('');
	....
	const [stateN, stateNSetFunc] = useState('');

This prevents having to use one big state object - you can have many little state objects.
Another way would be to write your own merge function for state update, but this would be
harder to do.


State Update Batching
- - - - - - - - - - - -
React will batch calls to setState hook functions to avoid unnecessary render cycles.

All state updates from one SYNCRHONOUS event handler are BATCHED TOGETHER.

Thus, after setting state, a lot like in class components, you can't immediately use the state
to get the new value.

Also it means the same applies for state that depends on previous state.
	const [counter, setCounter] = useState(0);
	...
	setCount(counter + 1); //< BAD BAD BAD BAD
	setCounter( prevCounter => prevCounter + 1); // Way better


Lazy Eval and Gotcha When Storing Functions As State
- - - - - - - - - - - - - - - - - - - - - - - - - - -
If the initial value is expensive to calculate it can be provided as a function that will only
be executed on the *first render* to setup the state.

This has the impact that if you use a state variable to store a callback function it wont work
as expected (although this might be an anti-pattern?!).

	// In the parent...
	[callback, setCallback] = useState(()=>{});

	// Then a child component might
	setCallback(() => someFunction(...));

	// Then back in the parent
	callback(); //<<< Error callback is whatever someFunction(...) returns or undefined if its a method!

To overcome this use

	setCallback(() => () => someFunction(...))
	//          ^^^^^
	//          Note the extra indirection. Needed because the passed in function is called by
	//          react to calculate the state, and as this returns a function the inner function can
	//          then be the state



useEffect()
===========
SEE: https://reactjs.org/docs/hooks-effect.html
also https://sebhastian.com/react-hooks-useeffect/

An "effect" or "side effect" is anything that lies outside React's responsibilities of rendering
the app, responding to user events and re-rendering. I.e. they are tasks that happen outside of the
normal component evaluation and render cycle. So, for example, an AJAX query is something
that happens outside of React's purview. Or, storing something in browser storage etc.

import React, {useState, useEffect} from 'react';

Use effect allows one to manage side effects:

	The Effect Hook lets you perform side effects in function components.
	...
	Data fetching, setting up a subscription, and manually changing the DOM in React components are
	all examples of side effects
	...
	 you can think of useEffect Hook as componentDidMount, componentDidUpdate, and
	 componentWillUnmount combined.

Side effects = Logs that runs and does effect the application but not in the current render cycle,
i.e., a future cycle.

useEffect() gets used AFTER EVERY render cycle.

You need useEffect() for exactly the same reason you dont trigger side effects in a class based
render function - you enter an infinite loop where each time you render you create a side effect
that modifies the state and triggers a re-render and so on...

Use it like this:
	useEffect(FUNCTION, DEPENDENCIES-OF-FUNCTION);

So, your function is only run when the dependencies are modified. This is how you can get it to
act like componentDidMount or componenetDidUpdate etc. The default, is, as mentioned for every
render cycle, but using dependencies, you can change this...

Dependencies are variables you use outside of useEffect in your function. React hook functions
used in useEffect do not have to be considered external dependencies.

If you ommit DEPENDENCIES-OF-FUNCTION then it runs FOR EVERY render cycle.

If you make it an empty list then it only runs for the very FIRST render - i.e., like
componentDidMount().



You can have multiple useEffect() calls, just like you do with useState().

To use dependencies:

	let [myState, setMyState] = useState(myDefaultState);

	...

	useEffect( ()=> {...}, [myState] ); //<<< This only executes when myState is changed.

This can allow us to split logic more elegantly. For example, if we fetch data based on whether
a checkbox is selected, our onChange event function can just manage the checked state and we can
split out the fetch logic into a useEffect() call with a dependency on the checkbox state.

If you rely on props in an effect then declare them as a dependency - PROPS ARE ALSO DEPENDENCIES
if you use them.

	This effect is called whn ANY prop changes:
		useEffect( () => {...}, [..., props]);

	This effect will be called only when a certain key in the props changes:
		const { keyName } = props;
		...
		useEffect( () => {...}, [..., keyValue]);

If you don't use the deps parameter properly you can get a "closure trap of a hook": see https://betterprogramming.pub/understanding-the-closure-trap-of-react-hooks-6c560c408cde.

This is also a *really* super read with a React hooks closure trap problem: https://betterprogramming.pub/a-react-hooks-challenge-for-senior-react-developers-f1190e1939ec
	
	A really important knuget of knowledge from the above article is this:
	
		In `const [myList, setMyList] = useState([])` the list returned by each call to 
		useState is calculated based on the following formula:
			base state + update1 + update2 + … = current state
		... So, the list returned by multiple calls to useState are different objects with different
		addresses in memory.

	It also makes it very clear as to why when setting state based on prev state, one should use
	`setMyList( prevList => prevList.concat(...))`

	For a good explanation of closures see: https://betterprogramming.pub/10-javascript-closure-challenges-explained-with-diagrams-c964110805e7


Clean Up With useEffect():
- - - - - - - - - - - - - -
useEffect() can return a FUNCTION. A return value is not required, but if provided MUST be a func!
The function returned is a CLEANUP function that will run before the next time useEffect() runs. Note,
this is NOT after the useEffect() runs, but BEFORE the next useEffect() is run.

If useEffect() has [] as its dependency, and therefore only runs once when the component is first
rendered then the returned function is equivalent to componentWillUnmount()!


useCallback()
=============
SEE: https://reactjs.org/docs/hooks-reference.html#usecallback

	Pass an inline callback and an array of dependencies. useCallback will return a memoized version
	of the callback that only changes if one of the dependencies has changed. This is useful when
	passing callbacks to optimized child components that rely on reference equality to prevent
	unnecessary renders (e.g. shouldComponentUpdate).

Save a function so that it is not re-created.

This can be very useful to get out of entering infinite loops in render cycles. The course example
was where a parent passes a callback function, X, to a child that uses an effect that depends on XMLHttpRequestObject
and calls X, which modidifies the parent state. Because, when the parent re-renders, the callback function
is redefined, the child will trigger its effect again creating this infinite loop. The way to stop this is
to preserve the callback function across render cycles, so that it doesn't change due to a render and
therefore the child won't call X because of the prop callback function change.

Often used in combination with React.memo() and vice versa, when a function being passed to a child
as a callback would otherwise change, making the memoisation unable to see the props as unchanged.


useMemo()
=========

Save a value so that it is not continually recreated.

For example, a component has a list of values. It is re-rendered, but not because of a change to
the list. Thus, do not want to re-create the components that result from the list. Save the
generated components using `useMemo()`.

	const someComponentList = useMemo( () => {
		return <MyComponentList .../>
	}, [...dependencies...]);


useRef()
========
Allows use of references as you might do in class components.
	const myRef = useRef();
	...
	<SomeElement ref={myRef}/ ...>

Remember to add the ref as a DEPENDENCY if you use it in an effect!


useReducer()
============
SEE: https://reactjs.org/docs/hooks-reference.html#usereducer
     const [state, dispatch] = useReducer(reducer, initialArg, init);
     An alternative to useState. Accepts a reducer of type (state, action) => newState, and returns
		 the current state paired with a dispatch method. (If you’re familiar with Redux, you already
		 know how this works, altough NOT related to Redux otherwise).

The reducer functions that you define are a lot like Redux reducers because they accept the
current state and an action. Based on the action and current state, the reducer must return the
new state.

	const myReducerForSomeThing = (currentThingState, action) => {
		switch(action.type) { // << The action is whatever we dispatched - its type isd't predefined
			case 'SOME ACTION:
				return newStateBasedOnCurrentThingStateForSomeAction;
			...
			default:
				throw new Error("Should never happen - all actions should be handled");
		}
	};

	...

	const MyElement = () => {
		const [myThingState, dispatch	] = useReducer(myReducerForSomeThing, initial-state);

		const someHandler = () => {
			dispatch({type: "SOME ACTION", ...});
		}
	}

React will re-render the component WHENEVER YOUR REDUCER RETURNS NEW STATE.

Reducers can make things cleaner as all of the update logic is located in one place. Makes a
clearer flow of data.

For HTTP requrests
	Sending the request is an action. Action = SEND. (But update state dont do the actual send)
	Handling the reply. Action = RESPONSE.
	Handling any errors. Action = ERROR.

Reducers must be PURE FUNCTIONS:
	A pure function is a function which:
		Given the same input, will always return the same output.
		Produces no side effects.
	A dead giveaway that a function is impure is if it makes sense to call it without using its
	return value. For pure functions, that’s a noop.
	A pure function produces no side effects, which means that it can’t alter any external state.
	Therefore, you can't do AJAX requests from a reducer. Instead use ACTION CREATORS.


useContext()
============
Is the equivalent hook to the class context setup using the member variable `static contextType = ...;`
You build the provider as per normal

Instead, now do:

	import { MyContext } from ...;

	const SomeComponent = props => {
		const myContext = useContent(MyContext);
	};


CUSTOM HOOKS
============
SEE: https://reactjs.org/docs/hooks-custom.html

	Hooks are a new addition in React 16.8. They let you use state and other React features without
	writing a class.

* Share logic that influences component state across many different components.
* Custom hooks should always be named `useXXXX`.
* Inside hook functions you can use stateful features like useState() or useEffect(), for example.
  The stateful logic is reusable but the data it manipulates is specific to the component using
  the custom hook :)




Deploying To The Web

1. Remeber to add the basename attribute to <BrowserRouter/> if app is not being served from the root
   of the domain it is hosted on. So if serving from www.jeh-tech.com, no need, but if serving from
   www.jeh-tech.com/apps/app1, the need <BrowserRouter basename="/apps/app1/">....<.BrowserRouter>.
2. Build and optimise the site using
	npm run build (in your project directory)
3. Server must *always* serve the index.html file, even for 404 cases! Server gets the paths before
   the react app gets the path and server won't know the app paths!!
4. Upload build artifacts from step 2 to a static server (Firebase, GitHub pages, AWS S3 etc etc).
	I.e., the content of the build folder!


Remove &quot; Download the React DevTool...&quot Message
------------------------------------------------------
See: https://stackoverflow.com/a/42196820/1517244
    __REACT_DEVTOOLS_GLOBAL_HOOK__ = {
      supportsFiber: true,
      inject: function() {},
      onCommitFiberRoot: function() {},
      onCommitFiberUnmount: function() {},
    };



Webpack

A bundler, a file optimizer, file transformer and transpiler (ES modern to legacy for eg). Takes
multiple HTML, JS, image etc etc resources and bundles them together with optimization etc.

1. Create folder to hold project
2. Get NPM to manage dependencies.
   In project folder type:
      npm init
   Creates "package.json".



TODO - Complete sectioN!



Third Party Components

https://react-bootstrap.github.io/ - Really good - lots of pre-styled components
https://minicss.org/               - Build websites on any and all devices, beautiful & load fast. < 10KB.
https://momentjs.com/              - Parse, validate, manipulate and display dates and times in JS
https://bernii.github.io/gauge.js/ - 
https://formidable.com/open-source/victory - React.js components for modular charting and data visualization.
https://uber.github.io/react-vis/examples/showcases/plots



React Fiber

Prev (before React 16) reconcillation algorithm was "Stack Reconciler". It was entirely synchronous
and has only one phase.

Reconcillation - The algorithm React uses to diff one tree with another to determine which parts
                 need to be changed.

When state changes, react generates an intermediate virtual DOM and compares it against the previous
virtual DOM before the state change. It uses this diff to update select portions of the browser DOM,
as opposed to updating the whole browser DOM - efficient.

The virtual DOMs are generated from Fiber's INTERNAL INSTANCE TREE, which is a tree of React
component instances and DOM nodes.

React Fibre is the new reconcillation algorithm included since React 16.

Reconcillation saves the developer from the need to keep track of what has changed and change the
browser DOM appropriately. All this "house keeping" is now done for the developer.

Virtual DOM- The tree of IMMUTABLE React elements returned from the render methods

Why the new reconcillation algorithm? Previously, when the rendering process started, it could not
be paused - the whole process had to be done in one go, in the browser main thread. Result can
be laggy user experience.

Unlike previous alg, Fiber has ability to minimize and batch DOM changes to minimise how long the
main thread is held for. It manipulates the main thread to enable async behaviour.

Once a render method returns its sub-tree of react components, they are merged into the tree of
fiber nodes - fiber analyses the components and creates corresponding fiber nodes that it inserts
into its own tree. I.e., every react element has a corresponding fiber node. Unlike React elements,
FIBERS ARE NOT RE-CREATED ON EVERY RENDER! The Fibre data structures, are, unlike the React
components, mutable. They hold component state and DOM state.

Fiber uses a LINKED LIST TREE TRAVERSAL ALGORITHM and an ASYNCHONOUS model that uses this list to
peocess elements that have pending work associated with them.

The Fiber process has TWO TREES:
1. Current tree
   After the very first render, represents state of app used to render to UI
2. Work-in-progress tree
   Built for the current update. Reflects the future app state that should eventually appear in the
	 browser.

It has TWO main PHASES:
1. Reconcile
   Mark fiber nodes with (side) effects asynchronously.
   Build up the WIP tree and the list of changes to be made but do NOT make those changes.
   This can be done asynchronously so that the main browser thread is not held for too long. It
   can be repeated/restarted multiple times as updates come in.

   It relies on a new browser API called `requestIdCallback`, which queues a function to be called
   during a browser's idle periods. It enables developers to perform background and low priority work
   on the main event loop, without impacting latency-critical events such as animation and input
   response. See https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback

   Of course, IE doesn't support this at the time of writing, but Chrome, Edge, Firefox and Opera do.

   Using this API, React can do the reconcillation phase during the browser's idle period by
	 splitting up its work into chunks and doing a chunk at a time. As it is
   called back, on each callback it can decide what chunk of work it wants to do, a lot like an OS
   scheduler would. The proprities are as follows:
      - synchonous    << HIGH
      - task
      - animation
      - high
      - low
      - offscreen     << LOW

   During this phase lifecycle hooks will be called:
      (UNSAFE_)componentWillMount
      (UNSAFE_)componentWillReceiveProps
      getDerivedStateFromProps
      shouldComponentUndpate
      (UNSAFE_)componentWillUpdated
      render

   Essentially, because, reca;;, JS is a single-threaded processes, using `requestIdCallback` React
   is able to fake a multi-threaded process using COOPERATIVE  MULTITASKING (a.k.a. NON-PREEMTIVE
   MULTITASKING).

   From WikiPedia:
      Cooperative multitasking, also known as non-preemptive multitasking, is a style of computer
      multitasking in which the operating system never initiates a context switch from a running
      process to another process. Instead, processes voluntarily yield control periodically or when
      idle or logically blocked in order to enable multiple applications to be run concurrently.
      This type of multitasking is called "cooperative" because all programs must cooperate for the
      entire scheduling scheme to work. In this scheme, the process scheduler of an operating system
      is known as a cooperative scheduler, having its role reduced down to starting the processes
      and letting them return control back to it voluntarily.

2. Commit
   This phase still has to be done synchronously, BUT the heavy lifting has been done in the prev
   phase, so this minimises the amount of time that the main browser thread is held for.
   This does the changes in the DOM - visible to user

   The following lifecycle hooks will be called:
      getSnapshotBeforeUpdate
      componentDidMount
      componentDidUpdate
      componentWillUnmount


Future?
Improve CPU utilisation using TIME SLICING
   - Rendering is NON BLOCKING - yields to use input
   - Multiple updates at different priorities
   - Pre render so as not to slow visiblecontent
Improve IO using React Suspense.
   - Access async data (e.g. from server) as easily as accessing sync data from member
   - Pause componentrender without blocking siblings
   - Precising control loading states to reduce jitter

React Suspense
--------------
https://reactjs.org/docs/concurrent-mode-suspense.html
    From Website:
		React 16.6 added a <Suspense> component that lets you "wait" for some code to load and
		declaratively specify a loading state (like a spinner) while waiting...


React Native

- Framework reslies on React core
- Supports iOS and Android. Microsoft also supports a version for Windows. Canonical also seem to
  support a version for the Ubuntu Desktop.

RNative
	- Bundles your Javascript
	- Threads for UI layout and JavaScript, which is different to ReacJS web.
		- Threads communicate through a "bridge". E.g. JS thread will request elements to be
		  rendered and the UI thread will render them and so on. This means, unlike in Web React
		  that the JS thread can block but the UI thread will remain responsive.

SEE snack.expo.io
    Its a nice little sandbox to play with react native and see how it renders in a fake phone.

Unfortunately it looks like an extra learning curve on top of learning how react works. I wanted to
try and change a large webapp to react-native but loads of tags need to be re-written. E.g. <div>
tags become <View> tags, <span> -> <Text> and stuff like this... so there would be some rework.
Also the proboperty names change too, like onClock becomes onPress. Seems like a faff.

If developing from scratch might have looked at this further, as it looks pretty powerful, but no
dice here so ending notes on react native.


Electron & React

Electron is a neat way of creating a NodeJS app that includes the Chromium browser to run
web apps on the desktop. It allows one to create CROSS PLATFORM apps.

Resources / References:
-----------------------
https://www.electronjs.org/docs/tutorial/quick-start
https://medium.com/@brockhoff/using-electron-with-react-the-basics-e93f9761f86f
https://www.freecodecamp.org/news/building-an-electron-application-with-create-react-app-97945861647c/
https://github.com/electron/windows-installer/issues/219#issuecomment-448188395
https://msanatan.com/2020/04/19/accessing-nodejs-modules-with-create-react-app-and-electron/


From the Electron docs:
	Electron consists of three main pillars:
		1. Chromium for displaying web content.
		2. Node.js for working with the local filesystem and the operating system.
		3. Custom APIs for working with often-needed OS native functions.
	Developing an application with Electron is like building a Node.js app with a web interface or
	building web pages with seamless Node.js integration.

Example:
--------
Had a little play with Elctron by embedding my little toy epic-planner app
(https://github.com/jameshume/epic_planner) using the the resources referenced above.

1. npm install --save-dev electron
2. add src/electron-main.js as described in the tutorials. including the freeCodeCamp's instructions
   on adding the ability to run from the NPM server for development and packaged build files for
	 release:
       const startUrl = process.env.ELECTRON_START_URL || url.format({
           pathname: path.join(__dirname, '../build/index.html'),
           protocol: 'file:',
           slashes: true
       });
       mainWindow.loadURL(startUrl);
   remember to set nodeIntegration to true in the BrowserWindow's webPreferences option:
      mainWindow = new BrowserWindow({
          ...
          webPreferences: { nodeIntegration: true }
      });
2. add the following additions to the package.json file:
	      ...
	+     "main": "src/electron-main.js",
	+     "homepage": "./",
	+     "author": "James Hume",
	+     "description": "A bare-bones epic planning application",
	      ...
	      "scripts": {
	          ....
	+         "electron": "electron .",
	+         "electron-dev": "set ELECTRON_START_URL=http://localhost:3000 && electron .",
	      }
	2.a The development version of the Electron app can be run by starting the NPM development server:
	    `npm start` and by then running the Electron app: `npm run electron-dev`.
	2.b The production version of the Electron app requires Electron forve... continue...
3. install Electron-Forge: (Needs Git, so on Windows run from Git Bash console)
	     npx @electron-forge/cli import
4. `npm run build` the application in preparation
5. on windows it appears, to get the the build to work correctly the following addition must be
   made to the forge config in the package.json file:
	     "config": {
	         "forge": {
	            "packagerConfig": {
	+               "asar": true
	            },
6. On windows, from Git bash terminal, `npm run make`.
7. Find your app in the "out" folder under the directory containing package.json.

Pretty frikin' awesome!!

Just note, Electron Forge might change the "start" script in your package.json file to
`"start": "electron-forge start",`... just be aware.


If you want to access Node.js modules do the following:
	(https://stackoverflow.com/a/44454923/1517244)
	use `window.require()` instead of `require()`:
	const fs = window.require('fs');


Access full filenames from HTML input element
---------------------------------------------
From https://stackoverflow.com/a/38549837/1517244
	Electron adds a path property to File objects, so you can get the real path from the input
	element using:
		document.getElementById("myFile").files[0].path

	In react just use a ref instead of getElementById!


Using Electron dialogs from React App
-------------------------------------



Typescript & React

Start a new project using:
	create-react-app my-app --template typescript
Add to an existing using:
	npm install --save-dev typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom