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.



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!



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
	!!
	!!	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, ...)}>



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.



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

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



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

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.



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().



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} 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}
			/>

	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>

	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 needto 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.

In submission event handler remember to use
	event.preventDefault();

IMPORTANT - Use event.preventDefault() otherwise form submission reloads the page!



Redux

See: https://redux.js.org/introduction/getting-started

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

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.



  Action -------------------------------> Reducer(s) 
    ^                     [Reaches]          |
    |                                        | [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 = (state = intialSate, action) => {
			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.
		const store = createStore(rootReducer)

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 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';


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

	// NOTE: Must WRAP the app with <Provider>
	ReactDOM.render(<Provider store={store}><App /></Provider>, ...);
	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;

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

	export default reducer;



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
			...
		}
	}

	// 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 => {
		return {
			a_props_attribute: state.some_state_var
			...
			...
		};
	}

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

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

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

	// Or
	export default connect(mapStateToProps)(null, mapDispatchToProps); // 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.



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-adaptor-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


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 =  hallow(<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
------------------




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!



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 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.