Simplest webpage with React from CDN The web page below uses React from CDN, creates root element by React functions and replaces elements in DOM
<html>
<body onload="myFunction()" />
<h1>React.js basics</h1>
<div id="demo" >This will be replaced by pure JavaScript</div>
<div id="react-app" >This will be replaced by React.js</div>
<div id="react-app1" >This will be replaced by React.js 1</div>
<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<script>
function myFunction() {
document.getElementById("demo").innerHTML = "Hello Wrold - Replaced by pure JavaScript";
var rootElement =
React.createElement('div', {},
React.createElement('h1', {}, "People"),
React.createElement('ul', {},
React.createElement('li', {},
React.createElement('h2', {}, "John First"),
React.createElement('a', {href: 'mailto:john@first.com'}, 'john@first.com')
),
React.createElement('li', {},
React.createElement('h2', {}, "Paul Second"),
React.createElement('a', {href: 'mailto:paul@second.com'}, 'paul@second.com')
)
)
)
ReactDOM.render(rootElement, document.getElementById('react-app'))
ReactDOM.render(rootElement, document.getElementById('react-app1'))
}
</script>
</body>
</html>
More info and samples on: www.devarchweb.net
What is JSX and how it compiles to JavaScript JSX aloows embedding hmlt tag into JavaScrip.var AboutPage = React.createClass({
render: funtion() {
return (
<div>
<h1 color="blue">About</h1>
<p>Demo page</p>
</div>
);
}
});
React.createElement("div", null,
React.createElement("h1", {color:"blue"}, "About" ),
React.createElement("p", null, "Demo page"},
)
More info and samples on: www.devarchweb.net
How to create simple webpage with About page as component Create about Page as a componentvar React = require('react'); // includes React package
var AboutPage = React.createClass({
render: function() {
return (
<div>
<h1 color="blue">About</h1>
<p>Demo page</p>
</div>
);
}
});
module.Export = AboutPage; // makes the page available
var React = require('react');
var AboutPage = require('./components/aboutPage'); // includes AbouPage component
React.render(<AboutPage>, document.getElementById('root')); // renders AboutPage in root element
<html>
<body>
<div id="root"></div>
<script src="scripts/bundle.js"></script> // gets created by gulp or webpack (all .js in one file)
</body>
</html>
More info and samples on: www.devarchweb.net
Differences in event handlers in ES5/6 Work in ES5<div onClick={this.handleClick}/>
<div onClick={this.handleClick.bind(this)}/>
class People extends React.Component{
constructor(props) {
super(props);
this.handleClick=this.handleClick.bind(this);
}
var ContactPage = function(props) {
return (
<h1> Main Street 1, Small City</h1>
);
});
const ContactPage = (props) => {
return (
<h1> Main Street 1, Small City</h1>
);
});
Stateless components do not have Lifecycle methods
More info and samples on: www.devarchweb.net
How to manage state in React Assuming there is a simple React component that renders first name from a Person class. this.Person.firstName
this.person = new Person('Paul');
this.forceUpdate()
this.state = new Person('John');
this.state.person.firstName
var newPerson = new Person('Paul');
this.setState(newPerson);
this.state = { "people" : people }
More info and samples on: www.devarchweb.net
How to create simple webpage with About page as component Assuming you have multiple components/pages and you need to defined mapping between page and url.var React = require('react');
var AboutPage = require('./components/aboutPage');
var Contact = require('./components/contact');
var AboutPage = React.createClass({
render: function() {
var Page;
switch (this.props.route) {
case 'contact' : Page = Contact; break;
default: Page = AboutPage;
}
return (
<div>
<Page/>
</div>
);
}
});
function render() {
var myRoute = window.location.hash.substr(1);
React.render(<App route = {myRoute} /> document.getElementById('root'));
}
window.addEventListener('hashchange', render); // listens to URL changes and renders new content
render(); // renders page first time
More info and samples on: www.devarchweb.net
How to use Router Router provider centralized way of handling routes. Create myRoutes.js that contains all mapping among urls and componentsvar React = require('react'); // includes React package
var myRoutes = (
<Route name="app" path="/" handler={require('./main')}>
<DefaultRoute handler=={require('./components/aboutPage'}>
// if path is not set, name is used
<Route name="people" path="allPeople" handler=={require('./components/people'}>
</Route>
);
}
});
module.Export = myRoutes;
var React = require('react');
var RouteHandler = require('react-router');
var myRoutes = require('./myRoutes');
var App = React.createClass({
render: function() {
return (
<div>
<RouteHandler/>
</div>
);
}
});
Router.run(myRoutes, function(Handler) {
React.render(<handler>, document.getElementById('root'));
});
More info and samples on: www.devarchweb.net
Describe properties and state this.props.userName - immutable - passd to child components from top level componentMore info and samples on: www.devarchweb.net
Lifecycle events Lifecycle:More info and samples on: www.devarchweb.net
how to display a listvar People = React.createClass({
// initial state is an empty array
getInitialState: function() {
return {
people: []
};
},
// loads data in json format and assigns them to people
componentWillMount: function() {
this.setState({ people: peopleService.getPeople() });
},
render: funtion() {
var createPersonText = function(person) {
return (
// id is necessary for the framework
<li key={author.id}>{person.firstName} {person.lastName}</li>
);
}
return (
<div>
<ul>
{this.state.people.map(createPersonText, this)}
</ul>
</div>
);
}
});
module.exports = People;
More info and samples on: www.devarchweb.net
What PropTypes are avaibale PropTypes help to validate if required parameters or/and types were passed to the component.More info and samples on: www.devarchweb.net
Set property expectations with PropTypesvar PeopleList = React.createClass({
propTypes: {
people: ReactPropTypes.array.isRequired
},
render: funtion() {
...
More info and samples on: www.devarchweb.net
Create store in code with Root reducer Configure store import {createStore} from 'redux';
import rootReducer from './myReducers';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState
}
import configureStore from './store/configureStore'
import {Provider} from 'react-redux'
const store = configureStore();
render(
<Provider store={store}>
<Router history={browseHistory routes={routes} />
</Provider>,
document.getElementById('root')
);
More info and samples on: www.devarchweb.net
Create action for 'create person' operationexport function createPerson(person) {
return { type: 'CREATE_PERSON', person};
}
// consts defined in an independent file
export const CREATE_PERSON = 'CREATE_PERSON';
import * as types from './actiontypes';
export function createPerson(person) {
return { type: types.CREATE_PERSON, person};
}
More info and samples on: www.devarchweb.net
Describe reducers in context of create person functionality Reducers are called by dispatch() method of store and return modified data as NEW ojectfunction myReducer(state, action) {
switch (action.type) {
case 'SET_NAME':
return (Object.assign({}, state, { name: 'John' });
default:
return state;
}
}
reducers/index.js
function arrayReducer(state =[], action) {
switch (action.type) {
case types.CREATE_PERSON:
return [...state, Object.assign({}, action.person)];
default:
return state;
}
}
More info and samples on: www.devarchweb.net
Describe Root reducer Using Root reducer simplifies multi case statementsimport {combineReducers} from 'redux';
import myReducer from './myReducerFile';
const rootReducer = combineReducers({
myReducer : myReducer
});
export default rootReducer;
More info and samples on: www.devarchweb.net
Simplest way using Redux "Redux Flow/Connect Container" chapterimport React,{PropTypes} from 'redux';
class People extends React.Component{
constructor(props) {
super(props, contect);
this.state = {
person:{ name:""}
};
this.OnNameChanged = this.OnNameChanged.bind(this);
this.OnClickCreate = this.OnClickCreate.bind(this);
}
onNameChanged(event) {
const person = this.state.person;
person.name = event.target.value;
setState({person:person});
}
onClickCreate() {
alert('${this.state.person.name} would be created here');
}
render() {
return (
<div>
<input type="text" onChange={this.onNameChanged} value{this.state.course.title} />
<input type="submit" onClick={this.onClickCreate} value="Create" />
</div>
);
}
}
export default PeoplePage;
import React,{PropTypes} from 'redux';
import {connect} from 'react-redux';
import * as personAction from './personActions';
class PeoplePage extends React.Component{
constructor(props) {
...
}
onClickCreate() {
// props.dispatch is injected by connect(), if connect uses only 1 argument
this.props.dispatch(personAction.createPerson(this.state.person));
}
personDetail(person, index) {
return <div key={index}>{person.name}</div>
}
render() {
return (
<div>
{this.props.people.map(this.personDetail)} //map() iterates over list - this line displays list
...
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
people: state.people
};
}
export default connect(mapStateToProps)(PeoplePage);
More info and samples on: www.devarchweb.net
Data flow with Redux after user clicks createPerson button "Step Through Redux Flow" chapter 4:50More info and samples on: www.devarchweb.net
How to use mapDispatchToProps()
import React,{PropTypes} from 'redux';
import {connect} from 'react-redux';
import * as personAction from './personActions';
class PeoplePage extends React.Component{
constructor(props) {
...
}
PeoplePage.PropTypes = {
people: PropTypes.array.isRequired,
createPerson: PropTypes.func.isRequired
}
onClickCreate() {
this.props.createPerson(this.state.person);
// before was: this.props.dispatch(personAction.createPerson(this.state.person));
}
personDetail(person, index) {
return <div key={index}>{person.name}</div>
}
render() {
return (
<div>
{this.props.people.map(this.personDetail)} //map() iterates over list - this line displays list
...
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
people: state.people
};
}
function mapDispatchToProps(dispatch) { // "dispatch" gets injected by the "connect()" function
return {
createPerson: person => dispatch(personActions.createPerson(person))
};
}
export default connect(mapStateToProps, mapDispatchToProps)(PeoplePage);
More info and samples on: www.devarchweb.net
How to use bindActionCreatorsimport React,{PropTypes} from 'redux';
import {connect} from 'react-redux';
import * as personAction from './personActions';
import {bindActionCreators} from 'redux';
class PeoplePage extends React.Component{
constructor(props) {
}
PeoplePage.PropTypes = {
people: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired,
}
onClickCreate() {
this.props.actions.createPerson(this.state.person);
}
render() {
return (
...
);
}
}
function mapStateToProps(state, ownProps) {
return {
people: state.people
};
}
function mapDispatchToProps(dispatch) { // "dispatch" gets injected by the "connect()" function
return {
actions: bindActionCreators(courseActions, dispatch); mapping all actions in personActions.js
// before was: createPerson: person => dispatch(personActions.createPerson(person));
};
}
export default connect(mapStateToProps, mapDispatchToProps)(PeoplePage);
More info and samples on: www.devarchweb.net
How to install MobX To install MobX run following
npm install mobx --save
npm install mobx-react --save
{
"compilerOptions": {
"experimentalDecorators": true
...
More info and samples on: www.devarchweb.net
How manage state with MobX@observer
class PersonPanel {
@observable person = new Person('John')
...
}
this.Person.firstName
onClick() {
this.person = new Person('Paul')
}
More info and samples on: www.devarchweb.net
How to confige Node for TypeScript debugging - seeing typeScript code In order to be able to see TyleScript code instead of compiled JavaScript code in debugger you need to add source mapper.package.json
"source-map-loader": "^0.1.5"
tsconfig.json
"compilerOptions": {
"sourceMap": true,
webpack.config.dev.js
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
module: {
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, loader: "source-map-loader" }
]
},
More info and samples on: www.devarchweb.net
How to use jQuery with TypeScript 1 Download jQuery Definition for TypeScript 1:/// <reference path="jquery.d.ts" />
var el1 = document.getElementById('content1');
el1.innerHTML = $("<div>ABC</div>").html();
More info and samples on: www.devarchweb.net
How to use jQuery with TypeScript 2 with node.js JavaScript 2 does not require to reference .d.ts in the code file. It uses a reference in package.jsonnpm install --save @types/<package>
"devDependencies": {
"@types/<package>": "<version>"
}
npm install
More info and samples on: www.devarchweb.net
How install and configure Mocha To install Mocha, update package.json:package.json
{
"devDependencies": {
...
"@types/mocha": "^2.2.34",
"mocha": "2.4.5",
...
}
}
package.json
{
"scripts": {
"pretest": "tsc",
"test": "mocha \"dist/**/*.test.js\"",
...
},
More info and samples on: www.devarchweb.net
How write a dummy test for Mocha Let's write a test. A dummy test to start to show the basics. 1 pass, 1 failexport class TestException {
message: string;
constructor(aMessage : string) {
this.message = aMessage;
}
};
describe('Dummy test demo', () => {
it('should PASS', () => {
// does nothing
});
it('should FAIL', () => {
throw new TestException("My failed test message");
});
});
npm test
More info and samples on: www.devarchweb.net
Write a test to test add() function Now something more real. Assuming there is a method add that needs to be testedimport * as myLib from './myLib';
describe('MyLib', () => {
it('WHEN add() called THEN correct value returned', () => {
// act
var result = myLib.add(1, 2);
// assert
var expected = 3;
if (result != expected) throw new TestException(result + " != " + expected);
});
});
More info and samples on: www.devarchweb.net
How to write test setup or tear downexport class TestException {
message: string;
constructor(aMessage : string) {
this.message = aMessage;
}
};
// Setup / Tear down
before(function(){
console.log(' Runs one time before the first test in the file')
})
after(function(){
console.log(' Runs one time after all tests in the file were executed')
})
beforeEach(function(){
console.log(' Runs before each test in the file')
})
afterEach(function(){
console.log(' Runs after each test in the file')
})
describe('Dummy test demo with setup/tear down', () => {
it('should PASS', () => {
// does nothing
});
it('should FAIL', () => {
throw new TestException("My failed test message");
});
});
More info and samples on: www.devarchweb.net
How to write custom test suite with setup or tear downfunction makeTestSuite(name:string, tests:any) {
describe(name, function () {
before(function () {
console.log(" executed before each test in the tst suite");
});
tests();
after(function () {
console.log(" executed before each test in the test suite");
});
});
}
makeTestSuite('Suite 1 - with setup', function(){
it('Test 1', function(done){
done();
});
it('Test 2', function(done){
done();
});
});
describe('Test Suite2 - without setup', function(){
it('Test 3', function(done){
done();
});
});
More info and samples on: www.devarchweb.net
Install Expect and write a test for add() function To install Expect, modify package.jsonpackage.json
"devDependencies": {
"@types/expect": "^1.13.31",
"expect": "1.19.0",
...
}
import * as myLib from './myLib';
import * as expect from 'expect';
describe('MyLib:', () => {
it('WHEN add() called THEN correct value returned', () => {
// act
var result = myLib.add(1, 2);
// assert
expect(result).toEqual(3);
});
});
More info and samples on: www.devarchweb.net
Install Chai and write a test for add() function To install Expect, modify package.jsonpackage.json
"devDependencies": {
"@types/chai": "3.4.30",
"chai": "^3.5.0"
...
}
import * as myLib from './myLib';
import * as chai from 'chai';
chai.should();
var expect = chai.expect;
var assert = chai.assert;
describe('MyLib:', () => {
it('WHEN add() called THEN correct value returned', () => {
// act
var result = myLib.add(1, 2);
// assert
// Option 1
expect(result).to.equals(3);
// expect(result).toEqual(3); 'expect' library style
// Option 2
result.should.equal(3);
// Option 3
assert.equal(result, 3);
});
});
More info and samples on: www.devarchweb.net
How to mock calls with 'expect' library'import * as expect from 'expect';
// method to be mocked
var myService = {
getValue: function () {}
}
describe('MyService:', () => {
// bypass call and return value
it('WHEN getValue() called THEN 3 returned', () => {
// arrange
var spy = expect.spyOn(myService, 'getValue')
var dice = spy.andReturn(3)
// act
var result = myService.getValue();
// assert
spy.restore()
expect(result).toEqual(3);
});
// fail if not called
it('WHEN test runs THEN FAIL if getValue() was not called', () => {
// arrange
var spy = expect.spyOn(myService, 'getValue')
// assert
expect(spy).toHaveBeenCalled('not called')
spy.restore()
});
});
More info and samples on: www.devarchweb.net
Compare Chai and Expect assertion libraries Feature Chai Expect