jest (basics)

ref – https://medium.com/piecesofcode/testing-javascript-code-with-jest-18a398888838

> mkdir jestTest
> cd jestTest
> npm init

> npm install —-save-dev jest

then in package.json:

make sure the “scripts” key, and its values are there.

Test Custom function

Let’s define a custom function.
concat.js

Then we test that custom function

concat.test.js

Basically, we use expect(…).toBe(…)

to make sure the returned result from our custom function matches up with what’s in toBe(…).

.toBe() basically just checks that value is what you expect it to be.

Testing custom objects

We can also declare a custom object, and then expect(…).toBe(…) an object.

matchers.test.js

Is the object in question equals given object?

Declare a null. Test if its a null. Test if its defined.

doing addition/subtraction with numerics

Check for elements in an array

Match a character in a string

callback

First we define the function getMessage, where we take a callback object parameter.
In the function getMessage, we pass in a string “go Javascript!”.

Then in our test, we define the callback function. In turn we pass in this callback function into the getMessage.

The way we test for the callback is to expect the value inside the callback function to be the string “go Javascript!”

React-Redux

In order to map redux store state to a component’s props, we start with the basic reducer functions.

Reducer is a pure (given an input, always return the same output) function that:

1) takes previous state as a parameter
2) takes an action as a parameter,
3) and returns the next state.

First, we declare our pure reducers. It returns an array of objects as state.

This gets returned to the property ‘contacts’ in reducers/index.js

reducers/index.js

The key here is the combineReducers function:

As your app grows more complex, you’ll want to split your reducing function into separate functions, each managing independent parts of the state.

The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to createStore.

the contacts will be used in a components, only when mapStateToProps gets called in that component, as will be shown later.

Pass to createStore

CreateStore and CombineReducers are often used together.

It may look like this:

Or it may look like this:

src/index.js

where the reducers are in another file, and we export it to be used.

Either way, we

1) first create the reducer functions.
2) combine them via combineReducers
3) Then create store

Provider’s prop store let’s children components access . data

Notice that App is within Provider.

or

The makes the Redux store available to any nested components that have been wrapped in the connect() function.

Since any React component in a React Redux app can be connected, most applications will render a at the top level, with the entire app’s component tree inside of it.

Normally, you can’t use a connected component unless it is nested inside of a < Provider >.

Hence, our App will be connected.

components/app.js

App is the main container. It houses two other components. Thus, the store data will be available to all containers.

Namely, these containers are ContactList and ContactDetail.

Mapping Redux store state to Component props

1) we map state to Contact List’s props in contact-list.js

Remember we had a reducer function called ContactsReducer that returns an array of objects.
Its property is contacts. We combined it with other reducers using combineReducers.

The contacts property is now available in our state object. However, this state object is available in mapStateToProps.

Now, look at “mapStateToProps”. Basically, it maps the state of (contacts) in the store into this component’s props.
Thus, after mapStateToProps is run, you’ll be able to do use it like so:

such as in renderList().

The important thing here is that once we declared our mapStateToProps function, we map it to the connect function.
Thus, whenever the data changes, it will call our mapStateToProps.

2) we map state to Contact Detail’s props in contact-detail.js

Let’s start at the basic level and look at the reducer function for activeContact.

It takes an action, so an action function will be executed first and then, passed in

Then this reducer function will look at the action object and determine what to do with it from its ‘type’ property.

where payload is

First, mapStateToProps gets called. It maps property ‘contact’ to redux store’s activeContact property in reducer/index.js
Then, in its render function, it can use it like so:

This expression is then used to display details, phone, and whatever attributes is available.

Mapping Action to Component props

Actions are plain javascript objects –

they are payloads of information that send data from your application to your store.

They are the ONLY source of information for the store. You send them to the store using store.dispatch().

In our case, when we return an action object with type and payload properties, they are called Action Creators.

Action creators are exactly that—functions that create actions.

In contact list component, there is an onClick handler, with

The selectMyContact is imported from actions/action-select-contact.js

That function is

when the handler is clicked, the action function selectMyContact is called.

Then reducer_active_contact in reducers/reducer_active_contact.js is called.

The action that gets passed through is the action object returned from selectMyContact.

thus, when it sees that its ‘CONTACT_SELECTED’, it will return the action.payload, which is the payload object from selectMyContact:

Using Redux in a React component

This is a react native app. Make sure you have expo installed.

demo

make sure to type ‘npm install’ to install all the packages.

Then type ‘npm start’.

Blogs
We install redux, and then import it for usage.

Comments

We import the store variable from Blogs.

AppContainer

Let’s configure our react navigation.
We also implemented our Blogs and Comments components above. We would use these components.

App.js

React Navigation basic example

Installation

yarn add react-navigation

or

npm install –save react-navigation

Creating Friends page (screen/Friends.js)

We create the Friends page. We navigate to the HomeScreen by using that string as the id.

Creating Home page (screen/Home.js)

Create a home page. Make sure any kind of text is wrapped in Text. We have a button, that upon the onPress event, navigates to our ‘FriendScreen’. This string is dictated by our AppContainer file below and used to navigate to the Friends page.

AppContainer

In the latest react navigation, we create an app container that houses a navigator.
We will be implementing this AppContainer in AppContainer.js:

For the AppNavigator object, notice the properties FriendsScreen and HomeScreen. They will be used as strings ids when other screens need to navigate…like so:

App.js

Passing into AppContainer

As you can see we pass in a prop called screenProp
It is an object, which we put inside of JS expression brackets.

In this object, we pass three properties.

1) current Friends array
2) possible Friends array
3) add Friends function

Retrieving the props data

In home, we retrieve it via this.props.

this.props.screenProps.currentFriends.length

In Friends, we use more of its features

Create a React Native App

ref – https://facebook.github.io/react-native/docs/getting-started.html

Install expo


npm install -g expo-cli

To create new React Project and run it

expo init SimpleApp

Then you’ll see a project is being created:

EPCNSZXW0324:testReactAppWithJest2 rickytsao$ expo init SimpleApp
There is a new version of expo-cli available (2.10.1).
You are currently using expo-cli 2.6.14
Run npm install -g expo-cli to get the latest version
? Choose a template: expo-template-blank
? Yarn v1.13.0 found. Use Yarn to install dependencies? Yes
[11:39:06] Extracting project files…
[11:39:09] Customizing project…
[11:39:10] Initialized a git repository.
[11:39:10] Installing dependencies…
yarn install v1.13.0
info No lockfile found.
[1/4] 🔍 Resolving packages…
[2/4] 🚚 Fetching packages…
[3/4] 🔗 Linking dependencies…
warning “expo > expo-background-fetch@1.0.0” has unmet peer dependency “expo-task-manager-interface@~1.0.0”.



warning “expo > babel-preset-expo > metro-react-native-babel-preset > @babel/plugin-proposal-object-rest-spread > @babel/plugin-syntax-object-rest-spread@7.2.0” has unmet peer dependency “@babel/core@^7.0.0-0”.
[4/4] 🔨 Building fresh packages…
success Saved lockfile.
✨ Done in 108.84s.

Your project is ready at /Users/rickytsao/Desktop/testReactAppWithJest2/SimpleApp
To get started, you can type:

cd SimpleApp
yarn start


cd SimpleApp
npm start

Then in the terminal:


> expo start

At this point, you are starting expo and it will run what you have in the current directory.

There is a new version of expo-cli available (2.10.1).
You are currently using expo-cli 2.6.14
Run npm install -g expo-cli to get the latest version
[13:11:22] Starting project at /Users/rickytsao/Desktop/testReactAppWithJest2/SimpleApp
[13:11:26] Expo DevTools is running at http://localhost:19002
[13:11:26] Opening DevTools in the browser… (press shift-d to disable)
[13:11:40] Starting Metro Bundler on port 19001.

exp://10.22.19.89:19000

you’ll also see a QR code image here

To run the app with live reloading, choose one of:
• Sign in as @rtsao6680 in Expo Client on Android or iOS. Your
projects will automatically appear in the “Projects” tab.
• Scan the QR code above with the Expo app (Android) or the Camera app (iOS).
• Press a for Android emulator, or i for iOS simulator.
• Press e to send a link to your phone with email/SMS.

Press ? to show a list of all available commands.
Logs for your project will appear below. Press Ctrl+C to exit.
[13:11:54] Tunnel ready.

A browser will open

On the left sidebar, under connection, “local” is selected.

Mosh React tutorial (part 2)

ref – https://www.youtube.com/watch?v=Ke90Tje7VS0&t=0s&list=LLJEwHxS-Vsf-N8xSFHeMirw&index=4

Handling Events

All those standard DOM events are available via the JSX.

We’ll use onClick and have it respond to our function handleIncrement.
However, when we execute the function, we notice that the this object is undefined.

Its because we need to bind the event handler.

But why is it that in an event handler function, the this object is undefined?

Depending on how a function is called, the ‘this’ changes.

The this reference will always return the calling object.

However, if the function is called as standalone, it will return window object.
If the standalone function is called within ‘strict mode’, it will return undefined.

And that is the reason, our event handler function does not have access to ‘this’.

Notice that its a handleIncrement REFERENCE. We didn’t execute the function yet. If the function was executed right away, then it will correctly call the function, and the function will be able to display this.

But for event handlers, since we pass the handleIncrement function reference, when it is used, it will be used in another function of a different environment. It will not be able have class Counter as its surrounding environment. It will be used in its own environment, namely, as a standalone function. Hence standalone functions (in a ‘strict mode’) will have undefined as the this object.

use ‘bind’ in the constructor

We implement a constructor function. Make sure you call super to initiate its parent class.
Then we bind the current this object to that function. So that when the reference of that function gets passed around, the this will always return to this object, and subsequently, the properties in this classCounter.

Use custom constructor to bind your event handlers to class Counter

Now, this.state.count will be valid.

use an arrow function

Updating the State

full code

What happens when State Changes

Let’s see what happens under the hood.

At this point, we call setState to tell React that the state of this component will change.

React will then schedule an async call to the render method. We don’t know when it happens, but it will happen in the future.

The render function will return a new React element. That element comes from the JSX code.

Hence, our virtual DOM is a div element, with span and button as its children.
We also have old virtual DOM. React will put them side by side and figure out what elements in the virtual DOM are modified.

It will notice that our span is modified because that’s where it has used formatCount().
So it will reach out to the real DOM, and update that span, in order to match what we have in the virtual DOM.

Go to the web page, Inspect Elements, and click on the ‘Increment’ button.
You’ll see that as you push the increment button, it calls

which updates the span. It updates the span because it depending on this.state.count it will update the class name to badge-primary or badge-info, and also update the count integer. Thus, in your Inspect Element, nothing else in the DOM is affected. Only that span element.

Passing Event Arguments

Mosh React tutorial (part 1)

ref – https://www.youtube.com/watch?v=Ke90Tje7VS0&t=0s&list=LLJEwHxS-Vsf-N8xSFHeMirw&index=4

Set up

Creating 1st app

EPCNSZXW0324:Desktop rickytsao$ create-react-app mosh-react-tut

Creating a new React app in /Users/rickytsao/Desktop/mosh-react-tut.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts…

> fsevents@1.2.4 install /Users/rickytsao/Desktop/mosh-react-tut/node_modules/fsevents
> node install

[fsevents] Success: “/Users/rickytsao/Desktop/mosh-react-tut/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node” is installed via remote
+ react-scripts@2.1.3
+ react-dom@16.7.0
+ react@16.7.0
added 1991 packages from 684 contributors and audited 35736 packages in 139.086s
found 0 vulnerabilities

Initialized a git repository.

Success! Created mosh-react-tut at /Users/rickytsao/Desktop/mosh-react-tut
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!

We suggest that you begin by typing:

cd mosh-react-tut
npm start

Happy hacking!
EPCNSZXW0324:Desktop rickytsao$

will install…

Development Server
Webpack
Babel
…other tools
etc

Now we have fully working react app..

> cd mosh-react-tut
> npm start

The app would start.

JSX (javscript xml)

– describe what UI will look like
– Babel takes JXS file, convert it to plain javascript code that browsers can understand.

Takes JXS file

convert it to javascript code:

– Babel compiles the JXS file, compile it to React Compoennt

ref – babeljs.io/repl

Write React code from scratch

in src, delete all files.

In src folder, Add file index.js

babel will compile it down to a call to React.createElement.

This is why we need to import React from top.

That was the output of a JS expression. Its a React Element.
virtual DOM lightweight in memory representation of the DOM.
React Element is part of virtual DOM.

React will then compare virtual DOM vs real DOM. See what has changed, and make changes accordingly.

index.js

Thus, you will get “Hello World” printed with div id root.

In real world, we don’t render elements like this.
We render Components instead.

We also render tree of components, which produce complex markup.

Components

First React Component

Create react app
start it up.

Open up Terminal.

Now, let’s import bootstrap into our app.

> npm i bootstrap@4.1.1

index.js

After saving, when you look at the web page, you’ll see that the font has turned purple.

In our folder view, under src, create a components folder.
Inside add a new file called counter.jsx

Earlier, we have installed Simple React Snippets…let’s use that now.

imrc + tab “import react component”
cc + tab “create class”

counter.jsx

Notice we’re defining the class above, and exporting it below

Now, let’s import Counter into our index.js file

Go back to your web page and you should see the text from Counter component

Embedding Expressions

add button to our Counter component

Note that JSX expressions must have 1 parent element.
JSX get compiled to React.createElement() where its argument is the type of element we want to create, i.e h1.

Thus, we must wrap what we want to display inside of an element, say a div.

counter.jsx

*Multi cursor editing – Select piece of code, press cmd + d, you’ll get multiple cursor, and change all instance in one go.

React Fragment

But let’s say you don’t like to wrap everything inside of an all encompassing element. You just want to put your fragmented code in the return expression.

Now when you look at the webpage, inspect the element, and you won’t see the div anymore.
You’ll see your html code underneath the id=root div.

Using state for dynamic data

First we override the state property in our Counter component.

We assign a property count to it.

Then in our JSX, we use curly braces and put any js expression inside of it.

save the changes, and you’ll see the results on your web page.

In between curly braces, you can write any valid javascript expression.
Hence, let’s implement a method, and use it within our curly braces.

Now, you will be able to see the string Zero when our count is 0.

We can also return JSX expression in our JS code.

JS expression like normal javascript. Pass them to a function, define const, variable…etc.

Setting Attributes

You can put set attributes via your js code as well. Let’s say we add a state property with a string to a url that generates a random image.

We put our ‘imageUrl’ property inside of the curly brace used in JSX and it will work like so:

Now, you’ll see the image in your output.

Remember that JSX gets compiled into React create element functions, which then outputs html. Hence, in our JSX, when we’re working with classes, we cannot just use class as attribute. We use ‘className’.

When we want to work with styles, we can create properties, which hold CSS data, which then changes dynamically. Those changes will be reflected in our JSX

inline styles

If you want to use inline styles, you can do another curly brace, and type in your styles like so:

Rendering Classes dynamically

We calculate bootstrap class name depending on if the count is 0 or not.
Then we render this calculation.

Thus, every time the page gets rendered, bootstrap’s “badge-warning” will be returned when the count is 0

and “badge-primary” will be returned when the count is not zero

Rendering Lists

Let’s render a list of tags.

We add new property of our state object.

JSX is NOT a TEMPLATE ENGINE, no concept of loops.

Its a simple syntax that gets compiled to React elements.

So we do it through javascript expressions via curly braces {…}

However, there is an error in the console.

Warning: Each child in an array or iterator should have a unique “key” prop.

The reason why is because it needs to uniquely identify each item in this list.
If the state of this react element changes, React needs to figure out quickly which element is changed.
And where in the DOM it needs to make changes so that it’s in sync with its virtual DOM.

Whenever you’re using the map method to render items, we need to set the ‘key’ attribute for our JSX.

Conditional Rendering – use curly braces for js expressions

Let’s spit out a message for when the tags are 0.
If there is some items in the tags array, then we simply display it.

JSX is not a templating engine. We do not have if/else. To put conditional rendering, we need to go back to our javascript.

We can add a helper method i.e renderTags().

Another technique is use condition in curly braces

The first js expression is if the boolean evaluates to true, we display a string.
The second js expression executes renderTags function.

First React Component

Create a reac component
then import bootstrap

open a terminal

npm i bootstrap@4.1.1

In file index.js:

Under src folder, create a new folder called components

in components folder, create a file counter.jsx

create basic React JS project

ref – https://code.visualstudio.com/docs/nodejs/reactjs-tutorial

We’ll be using the create-react-app generator for this tutorial.

Make sure you have Node.js JavaScript runtime and npm (Node.js package manager) installed.

To install the create-react-app generator, in a terminal or command prompt type:

npm install -g create-react-app

This may take a few minutes to install. You can now create a new React application by typing:

create-react-app my-app-one

This may take a few minutes to create the React application and install its dependencies.

Let’s quickly run our React application by navigating to the new folder and typing npm start to start the web server and open the application in a browser:


cd my-app-one
npm start

You should see “Welcome to React” on http://localhost:3000 in your browser. We’ll leave the web server running while we look at the application with VS Code.

To open your React application in VS Code, simply open the VS Code application and open the my-app-one folder.

Debugging React

To debug the client side React code, we’ll need to install the Debugger for Chrome extension.
Open the Extensions view and look for “Debugger for Chrome extension” in the search box. You’ll see several extensions which reference Chrome.
Press the Install button for Debugger for Chrome. The button will change to Installing then, after completing the installation, it will change to Reload. Press Reload to restart VS Code and activate the extension.

Set a breakpoint

To set a breakpoint in index.js, click on the gutter to the left of the line numbers. This will set a breakpoint which will be visible as a red circle.

Configure the Chrome debugger

We need to initially configure the debugger. To do so, go to the Debug view and click on the gear button to create a launch.json debugger configuration file. Choose Chrome from the Select Environment drop-down list. This will create a launch.json file in a new .vscode folder in your project which includes a configuration to launch the website.

We need to make one change for our example: change the port of the url from 8080 to 3000. Your launch.json should look like this:

Ensure that your development server is running (“npm start”). Then press fn+F5 or the green arrow
to launch the debugger and open a new browser instance. The source code where the breakpoint is set runs on startup before the debugger was attached so we won’t hit the breakpoint until we refresh the web page. Refresh the page and you should hit your breakpoint.