├── .gitignore
├── code
├── chapter01
│ └── snapterest
│ │ ├── source
│ │ ├── app.js
│ │ └── components
│ │ │ └── .empty
│ │ ├── gulpfile.js
│ │ ├── package.json
│ │ └── build
│ │ ├── index.html
│ │ └── snapterest.js
├── chapter02
│ └── snapterest
│ │ ├── source
│ │ ├── components
│ │ │ └── .empty
│ │ └── app.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── README.md
├── chapter09
│ └── snapterest
│ │ ├── source
│ │ ├── dispatcher
│ │ │ └── AppDispatcher.js
│ │ ├── utils
│ │ │ ├── TweetUtils.js
│ │ │ ├── CollectionUtils.js
│ │ │ └── __tests__
│ │ │ │ ├── TweetUtils-test.js
│ │ │ │ └── CollectionUtils-test.js
│ │ ├── app.js
│ │ ├── actions
│ │ │ └── TweetActionCreators.js
│ │ ├── components
│ │ │ ├── Button.react.js
│ │ │ ├── Header.react.js
│ │ │ ├── CollectionExportForm.react.js
│ │ │ ├── __tests__
│ │ │ │ ├── Button-test.js
│ │ │ │ └── Header-test.js
│ │ │ ├── Stream.react.js
│ │ │ ├── TweetList.react.js
│ │ │ ├── Tweet.react.js
│ │ │ ├── Application.react.js
│ │ │ ├── Collection.react.js
│ │ │ ├── CollectionRenameForm.react.js
│ │ │ ├── CollectionControls.react.js
│ │ │ └── StreamTweet.react.js
│ │ └── stores
│ │ │ └── TweetStore.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter10
│ └── snapterest
│ │ ├── source
│ │ ├── dispatcher
│ │ │ └── AppDispatcher.js
│ │ ├── utils
│ │ │ ├── TweetUtils.js
│ │ │ ├── WebAPIUtils.js
│ │ │ ├── CollectionUtils.js
│ │ │ └── __tests__
│ │ │ │ ├── TweetUtils-test.js
│ │ │ │ └── CollectionUtils-test.js
│ │ ├── app.js
│ │ ├── actions
│ │ │ ├── TweetActionCreators.js
│ │ │ └── CollectionActionCreators.js
│ │ ├── components
│ │ │ ├── Button.react.js
│ │ │ ├── Header.react.js
│ │ │ ├── CollectionExportForm.react.js
│ │ │ ├── Application.react.js
│ │ │ ├── __tests__
│ │ │ │ ├── Button-test.js
│ │ │ │ └── Header-test.js
│ │ │ ├── Stream.react.js
│ │ │ ├── Tweet.react.js
│ │ │ ├── TweetList.react.js
│ │ │ ├── Collection.react.js
│ │ │ ├── CollectionControls.react.js
│ │ │ ├── CollectionRenameForm.react.js
│ │ │ └── StreamTweet.react.js
│ │ └── stores
│ │ │ ├── TweetStore.js
│ │ │ └── CollectionStore.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter08
│ └── snapterest
│ │ ├── source
│ │ ├── utils
│ │ │ ├── TweetUtils.js
│ │ │ ├── CollectionUtils.js
│ │ │ └── __tests__
│ │ │ │ ├── TweetUtils-test.js
│ │ │ │ └── CollectionUtils-test.js
│ │ ├── app.js
│ │ └── components
│ │ │ ├── Button.react.js
│ │ │ ├── Header.react.js
│ │ │ ├── CollectionExportForm.react.js
│ │ │ ├── __tests__
│ │ │ ├── Button-test.js
│ │ │ └── Header-test.js
│ │ │ ├── Stream.react.js
│ │ │ ├── TweetList.react.js
│ │ │ ├── Tweet.react.js
│ │ │ ├── Application.react.js
│ │ │ ├── Collection.react.js
│ │ │ ├── CollectionRenameForm.react.js
│ │ │ ├── CollectionControls.react.js
│ │ │ └── StreamTweet.react.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter04
│ └── snapterest
│ │ ├── source
│ │ ├── app.js
│ │ └── components
│ │ │ └── Application.react.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter05
│ └── snapterest
│ │ ├── source
│ │ ├── app.js
│ │ └── components
│ │ │ ├── Stream.react.js
│ │ │ ├── Application.react.js
│ │ │ └── StreamTweet.react.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter06
│ └── snapterest
│ │ ├── source
│ │ ├── app.js
│ │ └── components
│ │ │ ├── Header.react.js
│ │ │ ├── Stream.react.js
│ │ │ ├── Tweet.react.js
│ │ │ ├── Application.react.js
│ │ │ ├── Collection.react.js
│ │ │ └── StreamTweet.react.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
├── chapter07
│ └── snapterest
│ │ ├── source
│ │ ├── app.js
│ │ └── components
│ │ │ ├── Button.react.js
│ │ │ ├── Header.react.js
│ │ │ ├── CollectionExportForm.react.js
│ │ │ ├── Stream.react.js
│ │ │ ├── TweetList.react.js
│ │ │ ├── Tweet.react.js
│ │ │ ├── Application.react.js
│ │ │ ├── Collection.react.js
│ │ │ ├── CollectionRenameForm.react.js
│ │ │ ├── CollectionControls.react.js
│ │ │ └── StreamTweet.react.js
│ │ ├── gulpfile.js
│ │ ├── build
│ │ └── index.html
│ │ └── package.json
└── chapter03
│ ├── stateless-component.js
│ └── stateful-component.js
├── update.sh
├── book-cover.jpg
├── artemij_snapchat.jpg
├── artemij_fedosejev.jpg
├── how-to-deploy.md
├── updates.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/code/chapter01/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/chapter01/snapterest/source/components/.empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/chapter02/snapterest/source/components/.empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | git add .
4 | git commit -m "Update"
5 | git push
--------------------------------------------------------------------------------
/book-cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fedosejev/react-essentials/HEAD/book-cover.jpg
--------------------------------------------------------------------------------
/artemij_snapchat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fedosejev/react-essentials/HEAD/artemij_snapchat.jpg
--------------------------------------------------------------------------------
/artemij_fedosejev.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fedosejev/react-essentials/HEAD/artemij_fedosejev.jpg
--------------------------------------------------------------------------------
/code/README.md:
--------------------------------------------------------------------------------
1 | ## React.js Essentials code
2 |
3 | Here you will find the latest version of the source code files for the book.
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/dispatcher/AppDispatcher.js:
--------------------------------------------------------------------------------
1 | var Dispatcher = require('flux').Dispatcher;
2 |
3 | module.exports = new Dispatcher();
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/dispatcher/AppDispatcher.js:
--------------------------------------------------------------------------------
1 | var Dispatcher = require('flux').Dispatcher;
2 |
3 | module.exports = new Dispatcher();
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/utils/TweetUtils.js:
--------------------------------------------------------------------------------
1 | function getListOfTweetIds(tweets) {
2 | return Object.keys(tweets);
3 | }
4 |
5 | module.exports.getListOfTweetIds = getListOfTweetIds;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/utils/TweetUtils.js:
--------------------------------------------------------------------------------
1 | function getListOfTweetIds(tweets) {
2 | return Object.keys(tweets);
3 | }
4 |
5 | module.exports.getListOfTweetIds = getListOfTweetIds;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/utils/TweetUtils.js:
--------------------------------------------------------------------------------
1 | function getListOfTweetIds(tweets) {
2 | return Object.keys(tweets);
3 | }
4 |
5 | module.exports.getListOfTweetIds = getListOfTweetIds;
--------------------------------------------------------------------------------
/code/chapter04/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter05/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 |
6 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var Application = require('./components/Application.react');
5 | var WebAPIUtils = require('./utils/WebAPIUtils');
6 |
7 | WebAPIUtils.initializeStreamOfTweets();
8 |
9 | ReactDOM.render(, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/actions/TweetActionCreators.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 |
3 | function receiveTweet(tweet) {
4 | var action = {
5 | type: 'receive_tweet',
6 | tweet: tweet
7 | };
8 |
9 | AppDispatcher.dispatch(action);
10 | }
11 |
12 | module.exports = {
13 | receiveTweet: receiveTweet
14 | };
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/actions/TweetActionCreators.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 |
3 | function receiveTweet(tweet) {
4 | var action = {
5 | type: 'receive_tweet',
6 | tweet: tweet
7 | };
8 |
9 | AppDispatcher.dispatch(action);
10 | }
11 |
12 | module.exports = {
13 | receiveTweet: receiveTweet
14 | };
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/utils/WebAPIUtils.js:
--------------------------------------------------------------------------------
1 | var SnapkiteStreamClient = require('snapkite-stream-client');
2 | var TweetActionCreators = require('../actions/TweetActionCreators');
3 |
4 | function initializeStreamOfTweets() {
5 | SnapkiteStreamClient.initializeStream(TweetActionCreators.receiveTweet);
6 | }
7 |
8 | module.exports = {
9 | initializeStreamOfTweets: initializeStreamOfTweets
10 | };
--------------------------------------------------------------------------------
/code/chapter01/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter02/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter04/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter05/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter06/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter07/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter08/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter09/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter10/snapterest/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var babelify = require('babelify');
4 | var source = require('vinyl-source-stream');
5 |
6 | gulp.task('default', function () {
7 | return browserify('./source/app.js')
8 | .transform(babelify)
9 | .bundle()
10 | .pipe(source('snapterest.js'))
11 | .pipe(gulp.dest('./build/'));
12 | });
--------------------------------------------------------------------------------
/code/chapter02/snapterest/source/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var listOfItems =
5 | - Item 1
6 | - Item 2
7 | - Item 3
8 |
;
9 |
10 | ReactDOM.render(listOfItems, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter01/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/chapter03/stateless-component.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var ReactClass = React.createClass({
5 | render: function () {
6 | return React.createElement('h1', { className: 'header' }, 'React Component');
7 | }
8 | });
9 |
10 | var reactComponentElement = React.createElement(ReactClass);
11 | var reactComponent = ReactDOM.render(reactComponentElement, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Button.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var buttonStyle = {
4 | margin: '10px 10px 10px 0'
5 | };
6 |
7 | var Button = React.createClass({
8 | render: function () {
9 | return (
10 |
14 | );
15 | }
16 | });
17 |
18 | module.exports = Button;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Button.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var buttonStyle = {
4 | margin: '10px 10px 10px 0'
5 | };
6 |
7 | var Button = React.createClass({
8 | render: function () {
9 | return (
10 |
14 | );
15 | }
16 | });
17 |
18 | module.exports = Button;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Button.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var buttonStyle = {
4 | margin: '10px 10px 10px 0'
5 | };
6 |
7 | var Button = React.createClass({
8 | render: function () {
9 | return (
10 |
14 | );
15 | }
16 | });
17 |
18 | module.exports = Button;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Button.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var buttonStyle = {
4 | margin: '10px 10px 10px 0'
5 | };
6 |
7 | var Button = React.createClass({
8 | render: function () {
9 | return (
10 |
14 | );
15 | }
16 | });
17 |
18 | module.exports = Button;
--------------------------------------------------------------------------------
/how-to-deploy.md:
--------------------------------------------------------------------------------
1 | # How to deploy a stand alone React.js application described in the book?
2 |
3 | Since React.js application is a JavaScript application, we can deploy it on GitHub Pages.
4 |
5 | ## How to deploy on GitHub Pages?
6 |
7 | 1. Create local `gh-pages` branch: `git checkout -b gh-pages`
8 | 2. Create remote `gh-pages` branch: `git push origin gh-pages`
9 | 3. Push changes in `build` directory to remote `gh-pages` branch: `git subtree push --prefix build origin gh-pages`
10 |
--------------------------------------------------------------------------------
/code/chapter01/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter02/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter04/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter05/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter06/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter07/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter08/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter09/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter10/snapterest/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Snapterest
7 |
8 |
9 |
10 |
11 | I am about to learn the essentials of React.js.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/code/chapter01/snapterest/build/snapterest.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o{this.props.text}
21 | );
22 | }
23 | });
24 |
25 | module.exports = Header;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Header.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var headerStyle = {
4 | fontSize: '16px',
5 | fontWeight: '300',
6 | display: 'inline-block',
7 | margin: '20px 10px'
8 | };
9 |
10 | var Header = React.createClass({
11 |
12 | getDefaultProps: function () {
13 | return {
14 | text: 'Default header'
15 | };
16 | },
17 |
18 | render: function () {
19 | return (
20 | {this.props.text}
21 | );
22 | }
23 | });
24 |
25 | module.exports = Header;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Header.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var headerStyle = {
4 | fontSize: '16px',
5 | fontWeight: '300',
6 | display: 'inline-block',
7 | margin: '20px 10px'
8 | };
9 |
10 | var Header = React.createClass({
11 |
12 | getDefaultProps: function () {
13 | return {
14 | text: 'Default header'
15 | };
16 | },
17 |
18 | render: function () {
19 | return (
20 | {this.props.text}
21 | );
22 | }
23 | });
24 |
25 | module.exports = Header;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/utils/CollectionUtils.js:
--------------------------------------------------------------------------------
1 | function getNumberOfTweetsInCollection(collection) {
2 | var TweetUtils = require('./TweetUtils');
3 | var listOfCollectionTweetIds = TweetUtils.getListOfTweetIds(collection);
4 |
5 | return listOfCollectionTweetIds.length;
6 | }
7 |
8 | function isEmptyCollection(collection) {
9 | return (getNumberOfTweetsInCollection(collection) === 0);
10 | }
11 |
12 | module.exports = {
13 | getNumberOfTweetsInCollection: getNumberOfTweetsInCollection,
14 | isEmptyCollection: isEmptyCollection
15 | };
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Header.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var headerStyle = {
4 | fontSize: '16px',
5 | fontWeight: '300',
6 | display: 'inline-block',
7 | margin: '20px 10px'
8 | };
9 |
10 | var Header = React.createClass({
11 |
12 | getDefaultProps: function () {
13 | return {
14 | text: 'Default header'
15 | };
16 | },
17 |
18 | render: function () {
19 | return (
20 | {this.props.text}
21 | );
22 | }
23 | });
24 |
25 | module.exports = Header;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/utils/CollectionUtils.js:
--------------------------------------------------------------------------------
1 | function getNumberOfTweetsInCollection(collection) {
2 | var TweetUtils = require('./TweetUtils');
3 | var listOfCollectionTweetIds = TweetUtils.getListOfTweetIds(collection);
4 |
5 | return listOfCollectionTweetIds.length;
6 | }
7 |
8 | function isEmptyCollection(collection) {
9 | return (getNumberOfTweetsInCollection(collection) === 0);
10 | }
11 |
12 | module.exports = {
13 | getNumberOfTweetsInCollection: getNumberOfTweetsInCollection,
14 | isEmptyCollection: isEmptyCollection
15 | };
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Header.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var headerStyle = {
4 | fontSize: '16px',
5 | fontWeight: '300',
6 | display: 'inline-block',
7 | margin: '20px 10px'
8 | };
9 |
10 | var Header = React.createClass({
11 |
12 | getDefaultProps: function () {
13 | return {
14 | text: 'Default header'
15 | };
16 | },
17 |
18 | render: function () {
19 | return (
20 | {this.props.text}
21 | );
22 | }
23 | });
24 |
25 | module.exports = Header;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/utils/CollectionUtils.js:
--------------------------------------------------------------------------------
1 | function getNumberOfTweetsInCollection(collection) {
2 | var TweetUtils = require('./TweetUtils');
3 | var listOfCollectionTweetIds = TweetUtils.getListOfTweetIds(collection);
4 |
5 | return listOfCollectionTweetIds.length;
6 | }
7 |
8 | function isEmptyCollection(collection) {
9 | return (getNumberOfTweetsInCollection(collection) === 0);
10 | }
11 |
12 | module.exports = {
13 | getNumberOfTweetsInCollection: getNumberOfTweetsInCollection,
14 | isEmptyCollection: isEmptyCollection
15 | };
--------------------------------------------------------------------------------
/code/chapter02/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | },
17 | "dependencies": {
18 | "react": "^0.14.0-beta3",
19 | "react-dom": "^0.14.0-beta3"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/chapter04/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | },
17 | "dependencies": {
18 | "react": "^0.14.0-beta3",
19 | "react-dom": "^0.14.0-beta3"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/chapter05/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | },
17 | "dependencies": {
18 | "react": "^0.14.0-beta3",
19 | "react-dom": "^0.14.0-beta3",
20 | "snapkite-stream-client": "^1.0.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/chapter06/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | },
17 | "dependencies": {
18 | "react": "^0.14.0-beta3",
19 | "react-dom": "^0.14.0-beta3",
20 | "snapkite-stream-client": "^1.0.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/chapter07/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babelify": "^6.2.0",
13 | "browserify": "^11.0.1",
14 | "gulp": "^3.9.0",
15 | "vinyl-source-stream": "^1.1.0"
16 | },
17 | "dependencies": {
18 | "react": "^0.14.0-beta3",
19 | "react-dom": "^0.14.0-beta3",
20 | "snapkite-stream-client": "^1.0.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/utils/__tests__/TweetUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../TweetUtils');
2 |
3 | describe('Tweet utilities module', function () {
4 | it('returns an array of tweet ids', function () {
5 | var TweetUtils = require('../TweetUtils');
6 |
7 | var tweetsMock = {
8 | tweet1: {},
9 | tweet2: {},
10 | tweet3: {}
11 | };
12 |
13 | var expectedListOfTweetIds = [ 'tweet1', 'tweet2', 'tweet3' ];
14 | var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock);
15 |
16 | expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds);
17 | });
18 | });
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/utils/__tests__/TweetUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../TweetUtils');
2 |
3 | describe('Tweet utilities module', function () {
4 | it('returns an array of tweet ids', function () {
5 | var TweetUtils = require('../TweetUtils');
6 |
7 | var tweetsMock = {
8 | tweet1: {},
9 | tweet2: {},
10 | tweet3: {}
11 | };
12 |
13 | var expectedListOfTweetIds = [ 'tweet1', 'tweet2', 'tweet3' ];
14 | var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock);
15 |
16 | expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds);
17 | });
18 | });
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/utils/__tests__/TweetUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../TweetUtils');
2 |
3 | describe('Tweet utilities module', function () {
4 | it('returns an array of tweet ids', function () {
5 | var TweetUtils = require('../TweetUtils');
6 |
7 | var tweetsMock = {
8 | tweet1: {},
9 | tweet2: {},
10 | tweet3: {}
11 | };
12 |
13 | var expectedListOfTweetIds = [ 'tweet1', 'tweet2', 'tweet3' ];
14 | var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock);
15 |
16 | expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds);
17 | });
18 | });
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/CollectionExportForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var formStyle = {
4 | display: 'inline-block'
5 | };
6 |
7 | var CollectionExportForm = React.createClass({
8 | render: function () {
9 | return (
10 |
15 | );
16 | }
17 | });
18 |
19 | module.exports = CollectionExportForm;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/CollectionExportForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var formStyle = {
4 | display: 'inline-block'
5 | };
6 |
7 | var CollectionExportForm = React.createClass({
8 | render: function () {
9 | return (
10 |
15 | );
16 | }
17 | });
18 |
19 | module.exports = CollectionExportForm;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/CollectionExportForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var formStyle = {
4 | display: 'inline-block'
5 | };
6 |
7 | var CollectionExportForm = React.createClass({
8 | render: function () {
9 | return (
10 |
15 | );
16 | }
17 | });
18 |
19 | module.exports = CollectionExportForm;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/CollectionExportForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var formStyle = {
4 | display: 'inline-block'
5 | };
6 |
7 | var CollectionExportForm = React.createClass({
8 | render: function () {
9 | return (
10 |
15 | );
16 | }
17 | });
18 |
19 | module.exports = CollectionExportForm;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 | render: function () {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | );
20 | }
21 | });
22 |
23 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/__tests__/Button-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Button.react');
2 |
3 | describe('Button component', function () {
4 | it('calls handler function on click', function () {
5 | var React = require('react');
6 | var TestUtils = require('react-addons-test-utils');
7 | var Button = require('../Button.react');
8 | var handleClick = jest.genMockFunction();
9 |
10 | var button = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var buttonInstance = TestUtils.findRenderedDOMComponentWithTag(button, 'button');
14 |
15 | TestUtils.Simulate.click(buttonInstance);
16 |
17 | expect(handleClick).toBeCalled();
18 |
19 | var numberOfCallsMadeIntoMockFunction = handleClick.mock.calls.length;
20 |
21 | expect(numberOfCallsMadeIntoMockFunction).toBe(1);
22 | });
23 | });
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/__tests__/Button-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Button.react');
2 |
3 | describe('Button component', function () {
4 | it('calls handler function on click', function () {
5 | var React = require('react');
6 | var TestUtils = require('react-addons-test-utils');
7 | var Button = require('../Button.react');
8 | var handleClick = jest.genMockFunction();
9 |
10 | var button = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var buttonInstance = TestUtils.findRenderedDOMComponentWithTag(button, 'button');
14 |
15 | TestUtils.Simulate.click(buttonInstance);
16 |
17 | expect(handleClick).toBeCalled();
18 |
19 | var numberOfCallsMadeIntoMockFunction = handleClick.mock.calls.length;
20 |
21 | expect(numberOfCallsMadeIntoMockFunction).toBe(1);
22 | });
23 | });
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/__tests__/Button-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Button.react');
2 |
3 | describe('Button component', function () {
4 | it('calls handler function on click', function () {
5 | var React = require('react');
6 | var TestUtils = require('react-addons-test-utils');
7 | var Button = require('../Button.react');
8 | var handleClick = jest.genMockFunction();
9 |
10 | var button = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var buttonInstance = TestUtils.findRenderedDOMComponentWithTag(button, 'button');
14 |
15 | TestUtils.Simulate.click(buttonInstance);
16 |
17 | expect(handleClick).toBeCalled();
18 |
19 | var numberOfCallsMadeIntoMockFunction = handleClick.mock.calls.length;
20 |
21 | expect(numberOfCallsMadeIntoMockFunction).toBe(1);
22 | });
23 | });
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/__tests__/Header-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Header.react');
2 |
3 | describe('Header component', function () {
4 | it('renders provided header text', function () {
5 | var React = require('react');
6 | var ReactDOM = require('react-dom');
7 | var TestUtils = require('react-addons-test-utils');
8 | var Header = require('../Header.react');
9 |
10 | var header = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var actualHeaderText = ReactDOM.findDOMNode(header).textContent;
14 |
15 | expect(actualHeaderText).toBe('Testing...');
16 |
17 | var defaultHeader = TestUtils.renderIntoDocument(
18 |
19 | );
20 | var actualDefaultHeaderText = ReactDOM.findDOMNode(defaultHeader).textContent;
21 |
22 | expect(actualDefaultHeaderText).toBe('Default header');
23 | });
24 | });
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/__tests__/Header-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Header.react');
2 |
3 | describe('Header component', function () {
4 | it('renders provided header text', function () {
5 | var React = require('react');
6 | var ReactDOM = require('react-dom');
7 | var TestUtils = require('react-addons-test-utils');
8 | var Header = require('../Header.react');
9 |
10 | var header = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var actualHeaderText = ReactDOM.findDOMNode(header).textContent;
14 |
15 | expect(actualHeaderText).toBe('Testing...');
16 |
17 | var defaultHeader = TestUtils.renderIntoDocument(
18 |
19 | );
20 | var actualDefaultHeaderText = ReactDOM.findDOMNode(defaultHeader).textContent;
21 |
22 | expect(actualDefaultHeaderText).toBe('Default header');
23 | });
24 | });
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/__tests__/Header-test.js:
--------------------------------------------------------------------------------
1 | jest.dontMock('../Header.react');
2 |
3 | describe('Header component', function () {
4 | it('renders provided header text', function () {
5 | var React = require('react');
6 | var ReactDOM = require('react-dom');
7 | var TestUtils = require('react-addons-test-utils');
8 | var Header = require('../Header.react');
9 |
10 | var header = TestUtils.renderIntoDocument(
11 |
12 | );
13 | var actualHeaderText = ReactDOM.findDOMNode(header).textContent;
14 |
15 | expect(actualHeaderText).toBe('Testing...');
16 |
17 | var defaultHeader = TestUtils.renderIntoDocument(
18 |
19 | );
20 | var actualDefaultHeaderText = ReactDOM.findDOMNode(defaultHeader).textContent;
21 |
22 | expect(actualDefaultHeaderText).toBe('Default header');
23 | });
24 | });
--------------------------------------------------------------------------------
/code/chapter08/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babel-jest": "^5.3.0",
13 | "babelify": "^6.2.0",
14 | "browserify": "^11.0.1",
15 | "gulp": "^3.9.0",
16 | "jest-cli": "^0.4.19",
17 | "react-addons-test-utils": "^0.14.0-beta3",
18 | "vinyl-source-stream": "^1.1.0"
19 | },
20 | "dependencies": {
21 | "react": "^0.14.0-beta3",
22 | "react-dom": "^0.14.0-beta3",
23 | "snapkite-stream-client": "^1.0.3"
24 | },
25 | "jest": {
26 | "scriptPreprocessor": "/node_modules/babel-jest",
27 | "testFileExtensions": [
28 | "es6",
29 | "js"
30 | ],
31 | "unmockedModulePathPatterns": [
32 | "/node_modules/react"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/code/chapter09/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babel-jest": "^5.3.0",
13 | "babelify": "^6.2.0",
14 | "browserify": "^11.0.1",
15 | "gulp": "^3.9.0",
16 | "jest-cli": "^0.4.19",
17 | "react-addons-test-utils": "^0.14.0-beta3",
18 | "vinyl-source-stream": "^1.1.0"
19 | },
20 | "dependencies": {
21 | "flux": "^2.1.1",
22 | "object-assign": "^4.0.1",
23 | "react": "^0.14.0-beta3",
24 | "react-dom": "^0.14.0-beta3",
25 | "snapkite-stream-client": "^1.0.3"
26 | },
27 | "jest": {
28 | "scriptPreprocessor": "/node_modules/babel-jest",
29 | "testFileExtensions": [
30 | "es6",
31 | "js"
32 | ],
33 | "unmockedModulePathPatterns": [
34 | "/node_modules/react"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/stores/TweetStore.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 | var EventEmitter = require('events').EventEmitter;
3 | var assign = require('object-assign');
4 | var tweet = null;
5 |
6 | function setTweet(receivedTweet) {
7 | tweet = receivedTweet;
8 | }
9 |
10 | function emitChange() {
11 | TweetStore.emit('change');
12 | }
13 |
14 | var TweetStore = assign({}, EventEmitter.prototype, {
15 |
16 | addChangeListener: function (callback) {
17 | this.on('change', callback);
18 | },
19 |
20 | removeChangeListener: function (callback) {
21 | this.removeListener('change', callback);
22 | },
23 |
24 | getTweet: function () {
25 | return tweet;
26 | }
27 | });
28 |
29 | function handleAction(action) {
30 | if (action.type === 'receive_tweet') {
31 | setTweet(action.tweet);
32 | emitChange();
33 | }
34 | }
35 |
36 | TweetStore.dispatchToken = AppDispatcher.register(handleAction);
37 |
38 | module.exports = TweetStore;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snapterest",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babel-jest": "^5.3.0",
13 | "babelify": "^6.2.0",
14 | "browserify": "^11.0.1",
15 | "gulp": "^3.9.0",
16 | "jest-cli": "^0.4.19",
17 | "react-addons-test-utils": "^0.14.0-beta3",
18 | "vinyl-source-stream": "^1.1.0"
19 | },
20 | "dependencies": {
21 | "flux": "^2.1.1",
22 | "object-assign": "^4.0.1",
23 | "react": "^0.14.0-beta3",
24 | "react-dom": "^0.14.0-beta3",
25 | "snapkite-stream-client": "^1.0.3"
26 | },
27 | "jest": {
28 | "scriptPreprocessor": "/node_modules/babel-jest",
29 | "testFileExtensions": [
30 | "es6",
31 | "js"
32 | ],
33 | "unmockedModulePathPatterns": [
34 | "/node_modules/react"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/stores/TweetStore.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 | var EventEmitter = require('events').EventEmitter;
3 | var assign = require('object-assign');
4 | var tweet = null;
5 |
6 | function setTweet(receivedTweet) {
7 | tweet = receivedTweet;
8 | }
9 |
10 | function emitChange() {
11 | TweetStore.emit('change');
12 | }
13 |
14 | var TweetStore = assign({}, EventEmitter.prototype, {
15 |
16 | addChangeListener: function (callback) {
17 | this.on('change', callback);
18 | },
19 |
20 | removeChangeListener: function (callback) {
21 | this.removeListener('change', callback);
22 | },
23 |
24 | getTweet: function () {
25 | return tweet;
26 | }
27 | });
28 |
29 | function handleAction(action) {
30 | if (action.type === 'receive_tweet') {
31 | setTweet(action.tweet);
32 | emitChange();
33 | }
34 | }
35 |
36 | TweetStore.dispatchToken = AppDispatcher.register(handleAction);
37 |
38 | module.exports = TweetStore;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/actions/CollectionActionCreators.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 |
3 | module.exports = {
4 |
5 | addTweetToCollection: function (tweet) {
6 | var action = {
7 | type: 'add_tweet_to_collection',
8 | tweet: tweet
9 | };
10 |
11 | AppDispatcher.dispatch(action);
12 | },
13 |
14 | removeTweetFromCollection: function (tweetId) {
15 | var action = {
16 | type: 'remove_tweet_from_collection',
17 | tweetId: tweetId
18 | };
19 |
20 | AppDispatcher.dispatch(action);
21 | },
22 |
23 | removeAllTweetsFromCollection: function () {
24 | var action = {
25 | type: 'remove_all_tweets_from_collection'
26 | };
27 |
28 | AppDispatcher.dispatch(action);
29 | },
30 |
31 | setCollectionName: function (collectionName) {
32 | var action = {
33 | type: 'set_collection_name',
34 | collectionName: collectionName
35 | };
36 |
37 | AppDispatcher.dispatch(action);
38 | }
39 | };
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var StreamTweet = require('./StreamTweet.react');
3 | var Header = require('./Header.react');
4 | var TweetStore = require('../stores/TweetStore');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: TweetStore.getTweet()
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | TweetStore.addChangeListener(this.onTweetChange);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | TweetStore.removeChangeListener(this.onTweetChange);
20 | },
21 |
22 | onTweetChange: function () {
23 | this.setState({
24 | tweet: TweetStore.getTweet()
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
34 | );
35 | }
36 |
37 | return (
38 |
39 | );
40 | }
41 | });
42 |
43 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/utils/__tests__/CollectionUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.autoMockOff();
2 |
3 | describe('Collection utilities module', function () {
4 |
5 | var CollectionUtils = require('../CollectionUtils');
6 | var collectionTweetsMock = {
7 | collectionTweet7: {},
8 | collectionTweet8: {},
9 | collectionTweet9: {}
10 | };
11 |
12 | it('returns a number of tweets in collection', function getNumberOfTweetsInCollection() {
13 | var actualNumberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweetsMock);
14 | var expectedNumberOfTweetsInCollection = 3;
15 |
16 | expect(actualNumberOfTweetsInCollection).toBe(expectedNumberOfTweetsInCollection);
17 | });
18 |
19 | it('checks if collection is not empty', function isNotEmptyCollection() {
20 | var actualIsEmptyCollectionValue = CollectionUtils.isEmptyCollection(collectionTweetsMock);
21 |
22 | expect(actualIsEmptyCollectionValue).toBeDefined();
23 | expect(actualIsEmptyCollectionValue).toBe(false);
24 | expect(actualIsEmptyCollectionValue).not.toBe(true);
25 | });
26 | });
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/utils/__tests__/CollectionUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.autoMockOff();
2 |
3 | describe('Collection utilities module', function () {
4 |
5 | var CollectionUtils = require('../CollectionUtils');
6 | var collectionTweetsMock = {
7 | collectionTweet7: {},
8 | collectionTweet8: {},
9 | collectionTweet9: {}
10 | };
11 |
12 | it('returns a number of tweets in collection', function getNumberOfTweetsInCollection() {
13 | var actualNumberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweetsMock);
14 | var expectedNumberOfTweetsInCollection = 3;
15 |
16 | expect(actualNumberOfTweetsInCollection).toBe(expectedNumberOfTweetsInCollection);
17 | });
18 |
19 | it('checks if collection is not empty', function isNotEmptyCollection() {
20 | var actualIsEmptyCollectionValue = CollectionUtils.isEmptyCollection(collectionTweetsMock);
21 |
22 | expect(actualIsEmptyCollectionValue).toBeDefined();
23 | expect(actualIsEmptyCollectionValue).toBe(false);
24 | expect(actualIsEmptyCollectionValue).not.toBe(true);
25 | });
26 | });
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/utils/__tests__/CollectionUtils-test.js:
--------------------------------------------------------------------------------
1 | jest.autoMockOff();
2 |
3 | describe('Collection utilities module', function () {
4 |
5 | var CollectionUtils = require('../CollectionUtils');
6 | var collectionTweetsMock = {
7 | collectionTweet7: {},
8 | collectionTweet8: {},
9 | collectionTweet9: {}
10 | };
11 |
12 | it('returns a number of tweets in collection', function getNumberOfTweetsInCollection() {
13 | var actualNumberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweetsMock);
14 | var expectedNumberOfTweetsInCollection = 3;
15 |
16 | expect(actualNumberOfTweetsInCollection).toBe(expectedNumberOfTweetsInCollection);
17 | });
18 |
19 | it('checks if collection is not empty', function isNotEmptyCollection() {
20 | var actualIsEmptyCollectionValue = CollectionUtils.isEmptyCollection(collectionTweetsMock);
21 |
22 | expect(actualIsEmptyCollectionValue).toBeDefined();
23 | expect(actualIsEmptyCollectionValue).toBe(false);
24 | expect(actualIsEmptyCollectionValue).not.toBe(true);
25 | });
26 | });
--------------------------------------------------------------------------------
/updates.md:
--------------------------------------------------------------------------------
1 | # Updates
2 |
3 | Unfortunately some errors are discovered after the book is published. Here I will describe updates for the current version of the book.
4 |
5 | ## Chapter 1, Page 14
6 |
7 | Instead of:
8 |
9 | `npm install --save-dev babelify`
10 |
11 | Use:
12 |
13 | `npm install --save-dev babelify@^6.2.0`
14 |
15 | ## Chapter 8, Page 6
16 |
17 | Instead of:
18 |
19 | `npm install --save-dev jest-cli`
20 |
21 | Use:
22 |
23 | `npm install --save-dev jest-cli@^0.4`
24 |
25 | ## Chapter 10, Page 29
26 |
27 | Instead of:
28 |
29 | ```js
30 |
31 | ```
32 |
33 | Use:
34 |
35 | ```js
36 |
37 | ```
38 |
39 | And instead of:
40 |
41 | ```js
42 |
43 | ```
44 |
45 | Use:
46 |
47 | ```js
48 |
49 | ```
50 |
51 | ## Found another error?
52 |
53 | Please contact Artemij: reactessentials@gmail.com
54 |
--------------------------------------------------------------------------------
/code/chapter03/stateful-component.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var ReactClass = React.createClass({
5 | getInitialState: function () {
6 | return {
7 | isHeaderHidden: false
8 | };
9 | },
10 |
11 | handleClick: function () {
12 | this.setState({
13 | isHeaderHidden: ! this.state.isHeaderHidden
14 | });
15 | },
16 |
17 | render: function () {
18 | var title = 'Stateful React Component';
19 | var headerElement = React.createElement('h1', { className: 'header', key: 'header' }, title);
20 | var buttonElement = React.createElement('button', { className: 'btn btn-default', onClick: this.handleClick, key: 'button' }, 'Toggle header');
21 |
22 | if (this.state.isHeaderHidden) {
23 | return React.createElement('div', null, [ buttonElement ]);
24 | }
25 |
26 | return React.createElement('div', null, [ buttonElement, headerElement ]);
27 | }
28 | });
29 |
30 | var reactComponentElement = React.createElement(ReactClass);
31 | var reactComponent = ReactDOM.render(reactComponentElement, document.getElementById('react-application'));
--------------------------------------------------------------------------------
/code/chapter05/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SnapkiteStreamClient = require('snapkite-stream-client');
3 | var StreamTweet = require('./StreamTweet.react');
4 | var Header = require('./Header.react');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: null
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | SnapkiteStreamClient.initializeStream(this.handleNewTweet);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | SnapkiteStreamClient.destroyStream();
20 | },
21 |
22 | handleNewTweet: function (tweet) {
23 | this.setState({
24 | tweet: tweet
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
36 | );
37 | }
38 |
39 | return (
40 |
41 | );
42 | }
43 | });
44 |
45 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SnapkiteStreamClient = require('snapkite-stream-client');
3 | var StreamTweet = require('./StreamTweet.react');
4 | var Header = require('./Header.react');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: null
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | SnapkiteStreamClient.initializeStream(this.handleNewTweet);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | SnapkiteStreamClient.destroyStream();
20 | },
21 |
22 | handleNewTweet: function (tweet) {
23 | this.setState({
24 | tweet: tweet
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
36 | );
37 | }
38 |
39 | return (
40 |
41 | );
42 | }
43 | });
44 |
45 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SnapkiteStreamClient = require('snapkite-stream-client');
3 | var StreamTweet = require('./StreamTweet.react');
4 | var Header = require('./Header.react');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: null
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | SnapkiteStreamClient.initializeStream(this.handleNewTweet);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | SnapkiteStreamClient.destroyStream();
20 | },
21 |
22 | handleNewTweet: function (tweet) {
23 | this.setState({
24 | tweet: tweet
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
36 | );
37 | }
38 |
39 | return (
40 |
41 | );
42 | }
43 | });
44 |
45 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SnapkiteStreamClient = require('snapkite-stream-client');
3 | var StreamTweet = require('./StreamTweet.react');
4 | var Header = require('./Header.react');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: null
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | SnapkiteStreamClient.initializeStream(this.handleNewTweet);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | SnapkiteStreamClient.destroyStream();
20 | },
21 |
22 | handleNewTweet: function (tweet) {
23 | this.setState({
24 | tweet: tweet
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
36 | );
37 | }
38 |
39 | return (
40 |
41 | );
42 | }
43 | });
44 |
45 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Stream.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SnapkiteStreamClient = require('snapkite-stream-client');
3 | var StreamTweet = require('./StreamTweet.react');
4 | var Header = require('./Header.react');
5 |
6 | var Stream = React.createClass({
7 |
8 | getInitialState: function () {
9 | return {
10 | tweet: null
11 | };
12 | },
13 |
14 | componentDidMount: function () {
15 | SnapkiteStreamClient.initializeStream(this.handleNewTweet);
16 | },
17 |
18 | componentWillUnmount: function () {
19 | SnapkiteStreamClient.destroyStream();
20 | },
21 |
22 | handleNewTweet: function (tweet) {
23 | this.setState({
24 | tweet: tweet
25 | });
26 | },
27 |
28 | render: function () {
29 | var tweet = this.state.tweet;
30 |
31 | if (tweet) {
32 | return (
33 |
36 | );
37 | }
38 |
39 | return (
40 |
41 | );
42 | }
43 | });
44 |
45 | module.exports = Stream;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/TweetList.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Tweet = require('./Tweet.react.js');
3 |
4 | var listStyle = {
5 | padding: '0'
6 | };
7 |
8 | var listItemStyle = {
9 | display: 'inline-block',
10 | listStyle: 'none'
11 | };
12 |
13 | var TweetList = React.createClass({
14 |
15 | getListOfTweetIds: function () {
16 | return Object.keys(this.props.tweets);
17 | },
18 |
19 | getTweetElement: function (tweetId) {
20 | var tweet = this.props.tweets[tweetId];
21 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
22 | var tweetElement;
23 |
24 | if (handleRemoveTweetFromCollection) {
25 |
26 | tweetElement = (
27 |
30 | );
31 |
32 | } else {
33 | tweetElement = ;
34 | }
35 |
36 | return {tweetElement};
37 | },
38 |
39 | render: function () {
40 | var tweetElements = this.getListOfTweetIds().map(this.getTweetElement);
41 |
42 | return (
43 |
44 | {tweetElements}
45 |
46 | );
47 | }
48 | });
49 | module.exports = TweetList;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/TweetList.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Tweet = require('./Tweet.react.js');
3 |
4 | var listStyle = {
5 | padding: '0'
6 | };
7 |
8 | var listItemStyle = {
9 | display: 'inline-block',
10 | listStyle: 'none'
11 | };
12 |
13 | var TweetList = React.createClass({
14 |
15 | getListOfTweetIds: function () {
16 | return Object.keys(this.props.tweets);
17 | },
18 |
19 | getTweetElement: function (tweetId) {
20 | var tweet = this.props.tweets[tweetId];
21 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
22 | var tweetElement;
23 |
24 | if (handleRemoveTweetFromCollection) {
25 |
26 | tweetElement = (
27 |
30 | );
31 |
32 | } else {
33 | tweetElement = ;
34 | }
35 |
36 | return {tweetElement};
37 | },
38 |
39 | render: function () {
40 | var tweetElements = this.getListOfTweetIds().map(this.getTweetElement);
41 |
42 | return (
43 |
44 | {tweetElements}
45 |
46 | );
47 | }
48 | });
49 | module.exports = TweetList;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/TweetList.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Tweet = require('./Tweet.react.js');
3 |
4 | var listStyle = {
5 | padding: '0'
6 | };
7 |
8 | var listItemStyle = {
9 | display: 'inline-block',
10 | listStyle: 'none'
11 | };
12 |
13 | var TweetList = React.createClass({
14 |
15 | getListOfTweetIds: function () {
16 | return Object.keys(this.props.tweets);
17 | },
18 |
19 | getTweetElement: function (tweetId) {
20 | var tweet = this.props.tweets[tweetId];
21 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
22 | var tweetElement;
23 |
24 | if (handleRemoveTweetFromCollection) {
25 |
26 | tweetElement = (
27 |
30 | );
31 |
32 | } else {
33 | tweetElement = ;
34 | }
35 |
36 | return {tweetElement};
37 | },
38 |
39 | render: function () {
40 | var tweetElements = this.getListOfTweetIds().map(this.getTweetElement);
41 |
42 | return (
43 |
44 | {tweetElements}
45 |
46 | );
47 | }
48 | });
49 | module.exports = TweetList;
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/components/Tweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var tweetStyle = {
4 | position: 'relative',
5 | display: 'inline-block',
6 | width: '300px',
7 | height: '400px',
8 | margin: '10px'
9 | };
10 |
11 | var imageStyle = {
12 | maxHeight: '400px',
13 | boxShadow: '0px 1px 1px 0px #aaa',
14 | border: '1px solid #fff'
15 | };
16 |
17 | var Tweet = React.createClass({
18 |
19 | propTypes: {
20 | tweet: function(properties, propertyName, componentName) {
21 | var tweet = properties[propertyName];
22 |
23 | if (! tweet) {
24 | return new Error('Tweet must be set.');
25 | }
26 |
27 | if (! tweet.media) {
28 | return new Error('Tweet must have an image.');
29 | }
30 | },
31 | onImageClick: React.PropTypes.func
32 | },
33 |
34 | handleImageClick: function () {
35 | var tweet = this.props.tweet;
36 | var onImageClick = this.props.onImageClick;
37 |
38 | if (onImageClick) {
39 | onImageClick(tweet);
40 | }
41 | },
42 |
43 | render: function () {
44 | var tweet = this.props.tweet;
45 | var tweetMediaUrl = tweet.media[0].url;
46 |
47 | return (
48 |
49 |

50 |
51 | );
52 | }
53 | });
54 |
55 | module.exports = Tweet;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Tweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var tweetStyle = {
4 | position: 'relative',
5 | display: 'inline-block',
6 | width: '300px',
7 | height: '400px',
8 | margin: '10px'
9 | };
10 |
11 | var imageStyle = {
12 | maxHeight: '400px',
13 | boxShadow: '0px 1px 1px 0px #aaa',
14 | border: '1px solid #fff'
15 | };
16 |
17 | var Tweet = React.createClass({
18 |
19 | propTypes: {
20 | tweet: function(properties, propertyName, componentName) {
21 | var tweet = properties[propertyName];
22 |
23 | if (! tweet) {
24 | return new Error('Tweet must be set.');
25 | }
26 |
27 | if (! tweet.media) {
28 | return new Error('Tweet must have an image.');
29 | }
30 | },
31 | onImageClick: React.PropTypes.func
32 | },
33 |
34 | handleImageClick: function () {
35 | var tweet = this.props.tweet;
36 | var onImageClick = this.props.onImageClick;
37 |
38 | if (onImageClick) {
39 | onImageClick(tweet);
40 | }
41 | },
42 |
43 | render: function () {
44 | var tweet = this.props.tweet;
45 | var tweetMediaUrl = tweet.media[0].url;
46 |
47 | return (
48 |
49 |

50 |
51 | );
52 | }
53 | });
54 |
55 | module.exports = Tweet;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Tweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var tweetStyle = {
4 | position: 'relative',
5 | display: 'inline-block',
6 | width: '300px',
7 | height: '400px',
8 | margin: '10px'
9 | };
10 |
11 | var imageStyle = {
12 | maxHeight: '400px',
13 | boxShadow: '0px 1px 1px 0px #aaa',
14 | border: '1px solid #fff'
15 | };
16 |
17 | var Tweet = React.createClass({
18 |
19 | propTypes: {
20 | tweet: function(properties, propertyName, componentName) {
21 | var tweet = properties[propertyName];
22 |
23 | if (! tweet) {
24 | return new Error('Tweet must be set.');
25 | }
26 |
27 | if (! tweet.media) {
28 | return new Error('Tweet must have an image.');
29 | }
30 | },
31 | onImageClick: React.PropTypes.func
32 | },
33 |
34 | handleImageClick: function () {
35 | var tweet = this.props.tweet;
36 | var onImageClick = this.props.onImageClick;
37 |
38 | if (onImageClick) {
39 | onImageClick(tweet);
40 | }
41 | },
42 |
43 | render: function () {
44 | var tweet = this.props.tweet;
45 | var tweetMediaUrl = tweet.media[0].url;
46 |
47 | return (
48 |
49 |

50 |
51 | );
52 | }
53 | });
54 |
55 | module.exports = Tweet;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Tweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var tweetStyle = {
4 | position: 'relative',
5 | display: 'inline-block',
6 | width: '300px',
7 | height: '400px',
8 | margin: '10px'
9 | };
10 |
11 | var imageStyle = {
12 | maxHeight: '400px',
13 | boxShadow: '0px 1px 1px 0px #aaa',
14 | border: '1px solid #fff'
15 | };
16 |
17 | var Tweet = React.createClass({
18 |
19 | propTypes: {
20 | tweet: function(properties, propertyName, componentName) {
21 | var tweet = properties[propertyName];
22 |
23 | if (! tweet) {
24 | return new Error('Tweet must be set.');
25 | }
26 |
27 | if (! tweet.media) {
28 | return new Error('Tweet must have an image.');
29 | }
30 | },
31 | onImageClick: React.PropTypes.func
32 | },
33 |
34 | handleImageClick: function () {
35 | var tweet = this.props.tweet;
36 | var onImageClick = this.props.onImageClick;
37 |
38 | if (onImageClick) {
39 | onImageClick(tweet);
40 | }
41 | },
42 |
43 | render: function () {
44 | var tweet = this.props.tweet;
45 | var tweetMediaUrl = tweet.media[0].url;
46 |
47 | return (
48 |
49 |

50 |
51 | );
52 | }
53 | });
54 |
55 | module.exports = Tweet;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Tweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var tweetStyle = {
4 | position: 'relative',
5 | display: 'inline-block',
6 | width: '300px',
7 | height: '400px',
8 | margin: '10px'
9 | };
10 |
11 | var imageStyle = {
12 | maxHeight: '400px',
13 | boxShadow: '0px 1px 1px 0px #aaa',
14 | border: '1px solid #fff'
15 | };
16 |
17 | var Tweet = React.createClass({
18 |
19 | propTypes: {
20 | tweet: function(properties, propertyName, componentName) {
21 | var tweet = properties[propertyName];
22 |
23 | if (! tweet) {
24 | return new Error('Tweet must be set.');
25 | }
26 |
27 | if (! tweet.media) {
28 | return new Error('Tweet must have an image.');
29 | }
30 | },
31 | onImageClick: React.PropTypes.func
32 | },
33 |
34 | handleImageClick: function () {
35 | var tweet = this.props.tweet;
36 | var onImageClick = this.props.onImageClick;
37 |
38 | if (onImageClick) {
39 | onImageClick(tweet);
40 | }
41 | },
42 |
43 | render: function () {
44 | var tweet = this.props.tweet;
45 | var tweetMediaUrl = tweet.media[0].url;
46 |
47 | return (
48 |
49 |

50 |
51 | );
52 | }
53 | });
54 |
55 | module.exports = Tweet;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/TweetList.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Tweet = require('./Tweet.react.js');
3 | var CollectionActionCreators = require('../actions/CollectionActionCreators');
4 |
5 | var listStyle = {
6 | padding: '0'
7 | };
8 |
9 | var listItemStyle = {
10 | display: 'inline-block',
11 | listStyle: 'none'
12 | };
13 |
14 | var TweetList = React.createClass({
15 |
16 | getListOfTweetIds: function () {
17 | return Object.keys(this.props.tweets);
18 | },
19 |
20 | removeTweetFromCollection: function (tweet) {
21 | CollectionActionCreators.removeTweetFromCollection(tweet.id);
22 | },
23 |
24 | getTweetElement: function (tweetId) {
25 | var tweet = this.props.tweets[tweetId];
26 | var handleRemoveTweetFromCollection = this.removeTweetFromCollection;
27 | var tweetElement;
28 |
29 | if (handleRemoveTweetFromCollection) {
30 |
31 | tweetElement = (
32 |
35 | );
36 |
37 | } else {
38 | tweetElement = ;
39 | }
40 |
41 | return {tweetElement};
42 | },
43 |
44 | render: function () {
45 | var tweetElements = this.getListOfTweetIds().map(this.getTweetElement);
46 |
47 | return (
48 |
49 | {tweetElements}
50 |
51 | );
52 | }
53 | });
54 | module.exports = TweetList;
--------------------------------------------------------------------------------
/code/chapter04/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter05/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Application.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Stream = require('./Stream.react');
3 | var Collection = require('./Collection.react');
4 |
5 | var Application = React.createClass({
6 |
7 | getInitialState: function () {
8 | return {
9 | collectionTweets: {}
10 | };
11 | },
12 |
13 | addTweetToCollection: function (tweet) {
14 | var collectionTweets = this.state.collectionTweets;
15 |
16 | collectionTweets[tweet.id] = tweet;
17 |
18 | this.setState({
19 | collectionTweets: collectionTweets
20 | });
21 | },
22 |
23 | removeTweetFromCollection: function (tweet) {
24 | var collectionTweets = this.state.collectionTweets;
25 |
26 | delete collectionTweets[tweet.id];
27 |
28 | this.setState({
29 | collectionTweets: collectionTweets
30 | });
31 | },
32 |
33 | removeAllTweetsFromCollection: function () {
34 | this.setState({
35 | collectionTweets: {}
36 | });
37 | },
38 |
39 | render: function () {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | });
63 |
64 | module.exports = Application;
--------------------------------------------------------------------------------
/code/chapter05/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 |
6 | var StreamTweet = React.createClass({
7 |
8 | getInitialState: function () {
9 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
10 |
11 | return {
12 | numberOfCharactersIsIncreasing: null,
13 | headerText: null
14 | };
15 | },
16 |
17 | componentWillMount: function () {
18 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
19 |
20 | this.setState({
21 | numberOfCharactersIsIncreasing: true,
22 | headerText: 'Latest public photo from Twitter'
23 | });
24 |
25 | window.snapterest = {
26 | numberOfReceivedTweets: 1,
27 | numberOfDisplayedTweets: 1
28 | };
29 | },
30 |
31 | componentDidMount: function () {
32 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
33 |
34 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
35 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
36 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
37 | },
38 |
39 | componentWillUnmount: function () {
40 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
41 |
42 | delete window.snapterest;
43 | },
44 |
45 | render: function () {
46 | console.log('[Snapterest] StreamTweet: Running render()');
47 |
48 | return (
49 |
55 | );
56 | }
57 | });
58 |
59 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/components/Collection.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 | var CollectionControls = require('./CollectionControls.react');
4 | var TweetList = require('./TweetList.react');
5 | var Header = require('./Header.react');
6 |
7 | var Collection = React.createClass({
8 |
9 | createHtmlMarkupStringOfTweetList: function () {
10 | var htmlString = ReactDOMServer.renderToStaticMarkup(
11 |
12 | );
13 |
14 | var htmlMarkup = {
15 | html: htmlString
16 | };
17 |
18 | return JSON.stringify(htmlMarkup);
19 | },
20 |
21 | getListOfTweetIds: function () {
22 | return Object.keys(this.props.tweets);
23 | },
24 |
25 | getNumberOfTweetsInCollection: function () {
26 | return this.getListOfTweetIds().length;
27 | },
28 |
29 | render: function () {
30 | var numberOfTweetsInCollection = this.getNumberOfTweetsInCollection();
31 |
32 | if (numberOfTweetsInCollection > 0) {
33 | var tweets = this.props.tweets;
34 | var htmlMarkup = this.createHtmlMarkupStringOfTweetList();
35 | var removeAllTweetsFromCollection = this.props.onRemoveAllTweetsFromCollection;
36 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
37 |
38 | return (
39 |
40 |
44 |
45 |
48 |
49 | );
50 | }
51 |
52 | return ;
53 | }
54 | });
55 |
56 | module.exports = Collection;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/Collection.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 | var CollectionControls = require('./CollectionControls.react');
4 | var TweetList = require('./TweetList.react');
5 | var Header = require('./Header.react');
6 |
7 | var Collection = React.createClass({
8 |
9 | createHtmlMarkupStringOfTweetList: function () {
10 | var htmlString = ReactDOMServer.renderToStaticMarkup(
11 |
12 | );
13 |
14 | var htmlMarkup = {
15 | html: htmlString
16 | };
17 |
18 | return JSON.stringify(htmlMarkup);
19 | },
20 |
21 | getListOfTweetIds: function () {
22 | return Object.keys(this.props.tweets);
23 | },
24 |
25 | getNumberOfTweetsInCollection: function () {
26 | return this.getListOfTweetIds().length;
27 | },
28 |
29 | render: function () {
30 | var numberOfTweetsInCollection = this.getNumberOfTweetsInCollection();
31 |
32 | if (numberOfTweetsInCollection > 0) {
33 | var tweets = this.props.tweets;
34 | var htmlMarkup = this.createHtmlMarkupStringOfTweetList();
35 | var removeAllTweetsFromCollection = this.props.onRemoveAllTweetsFromCollection;
36 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
37 |
38 | return (
39 |
40 |
44 |
45 |
48 |
49 | );
50 | }
51 |
52 | return ;
53 | }
54 | });
55 |
56 | module.exports = Collection;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/Collection.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 | var CollectionControls = require('./CollectionControls.react');
4 | var TweetList = require('./TweetList.react');
5 | var Header = require('./Header.react');
6 |
7 | var Collection = React.createClass({
8 |
9 | createHtmlMarkupStringOfTweetList: function () {
10 | var htmlString = ReactDOMServer.renderToStaticMarkup(
11 |
12 | );
13 |
14 | var htmlMarkup = {
15 | html: htmlString
16 | };
17 |
18 | return JSON.stringify(htmlMarkup);
19 | },
20 |
21 | getListOfTweetIds: function () {
22 | return Object.keys(this.props.tweets);
23 | },
24 |
25 | getNumberOfTweetsInCollection: function () {
26 | return this.getListOfTweetIds().length;
27 | },
28 |
29 | render: function () {
30 | var numberOfTweetsInCollection = this.getNumberOfTweetsInCollection();
31 |
32 | if (numberOfTweetsInCollection > 0) {
33 | var tweets = this.props.tweets;
34 | var htmlMarkup = this.createHtmlMarkupStringOfTweetList();
35 | var removeAllTweetsFromCollection = this.props.onRemoveAllTweetsFromCollection;
36 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
37 |
38 | return (
39 |
40 |
44 |
45 |
48 |
49 | );
50 | }
51 |
52 | return ;
53 | }
54 | });
55 |
56 | module.exports = Collection;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/Collection.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 | var CollectionControls = require('./CollectionControls.react');
4 | var TweetList = require('./TweetList.react');
5 | var Header = require('./Header.react');
6 |
7 | var Collection = React.createClass({
8 |
9 | createHtmlMarkupStringOfTweetList: function () {
10 | var htmlString = ReactDOMServer.renderToStaticMarkup(
11 |
12 | );
13 |
14 | var htmlMarkup = {
15 | html: htmlString
16 | };
17 |
18 | return JSON.stringify(htmlMarkup);
19 | },
20 |
21 | getListOfTweetIds: function () {
22 | return Object.keys(this.props.tweets);
23 | },
24 |
25 | getNumberOfTweetsInCollection: function () {
26 | return this.getListOfTweetIds().length;
27 | },
28 |
29 | render: function () {
30 | var numberOfTweetsInCollection = this.getNumberOfTweetsInCollection();
31 |
32 | if (numberOfTweetsInCollection > 0) {
33 | var tweets = this.props.tweets;
34 | var htmlMarkup = this.createHtmlMarkupStringOfTweetList();
35 | var removeAllTweetsFromCollection = this.props.onRemoveAllTweetsFromCollection;
36 | var handleRemoveTweetFromCollection = this.props.onRemoveTweetFromCollection;
37 |
38 | return (
39 |
40 |
44 |
45 |
48 |
49 | );
50 | }
51 |
52 | return ;
53 | }
54 | });
55 |
56 | module.exports = Collection;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/CollectionRenameForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Header = require('./Header.react');
3 | var Button = require('./Button.react');
4 |
5 | var inputStyle = {
6 | marginRight: '5px'
7 | };
8 |
9 | var CollectionRenameForm = React.createClass({
10 |
11 | getInitialState: function() {
12 | return {
13 | inputValue: this.props.name
14 | };
15 | },
16 |
17 | setInputValue: function (inputValue) {
18 | this.setState({
19 | inputValue: inputValue
20 | });
21 | },
22 |
23 | handleInputValueChange: function (event) {
24 | var inputValue = event.target.value;
25 | this.setInputValue(inputValue);
26 | },
27 |
28 | handleFormSubmit: function (event) {
29 | event.preventDefault();
30 | var collectionName = this.state.inputValue;
31 | this.props.onChangeCollectionName(collectionName);
32 | },
33 |
34 | handleFormCancel: function (event) {
35 | event.preventDefault();
36 | var collectionName = this.props.name;
37 | this.setInputValue(collectionName);
38 | this.props.onCancelCollectionNameChange();
39 | },
40 |
41 | componentDidMount: function () {
42 | this.refs.collectionName.focus();
43 | },
44 |
45 | render: function () {
46 | return (
47 |
62 | );
63 | }
64 | });
65 |
66 | module.exports = CollectionRenameForm;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/CollectionRenameForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Header = require('./Header.react');
3 | var Button = require('./Button.react');
4 |
5 | var inputStyle = {
6 | marginRight: '5px'
7 | };
8 |
9 | var CollectionRenameForm = React.createClass({
10 |
11 | getInitialState: function() {
12 | return {
13 | inputValue: this.props.name
14 | };
15 | },
16 |
17 | setInputValue: function (inputValue) {
18 | this.setState({
19 | inputValue: inputValue
20 | });
21 | },
22 |
23 | handleInputValueChange: function (event) {
24 | var inputValue = event.target.value;
25 | this.setInputValue(inputValue);
26 | },
27 |
28 | handleFormSubmit: function (event) {
29 | event.preventDefault();
30 | var collectionName = this.state.inputValue;
31 | this.props.onChangeCollectionName(collectionName);
32 | },
33 |
34 | handleFormCancel: function (event) {
35 | event.preventDefault();
36 | var collectionName = this.props.name;
37 | this.setInputValue(collectionName);
38 | this.props.onCancelCollectionNameChange();
39 | },
40 |
41 | componentDidMount: function () {
42 | this.refs.collectionName.focus();
43 | },
44 |
45 | render: function () {
46 | return (
47 |
62 | );
63 | }
64 | });
65 |
66 | module.exports = CollectionRenameForm;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/CollectionRenameForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Header = require('./Header.react');
3 | var Button = require('./Button.react');
4 |
5 | var inputStyle = {
6 | marginRight: '5px'
7 | };
8 |
9 | var CollectionRenameForm = React.createClass({
10 |
11 | getInitialState: function() {
12 | return {
13 | inputValue: this.props.name
14 | };
15 | },
16 |
17 | setInputValue: function (inputValue) {
18 | this.setState({
19 | inputValue: inputValue
20 | });
21 | },
22 |
23 | handleInputValueChange: function (event) {
24 | var inputValue = event.target.value;
25 | this.setInputValue(inputValue);
26 | },
27 |
28 | handleFormSubmit: function (event) {
29 | event.preventDefault();
30 |
31 | var collectionName = this.state.inputValue;
32 | this.props.onChangeCollectionName(collectionName);
33 | },
34 |
35 | handleFormCancel: function (event) {
36 | event.preventDefault();
37 |
38 | var collectionName = this.props.name;
39 | this.setInputValue(collectionName);
40 | this.props.onCancelCollectionNameChange();
41 | },
42 |
43 | componentDidMount: function () {
44 | this.refs.collectionName.focus();
45 | },
46 |
47 | render: function () {
48 | return (
49 |
64 | );
65 | }
66 | });
67 |
68 | module.exports = CollectionRenameForm;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/stores/CollectionStore.js:
--------------------------------------------------------------------------------
1 | var AppDispatcher = require('../dispatcher/AppDispatcher');
2 | var EventEmitter = require('events').EventEmitter;
3 | var assign = require('object-assign');
4 |
5 | var CHANGE_EVENT = 'change';
6 |
7 | var collectionTweets = {};
8 | var collectionName = 'new';
9 |
10 | function addTweetToCollection(tweet) {
11 | collectionTweets[tweet.id] = tweet;
12 | }
13 |
14 | function removeTweetFromCollection(tweetId) {
15 | delete collectionTweets[tweetId];
16 | }
17 |
18 | function removeAllTweetsFromCollection() {
19 | collectionTweets = {};
20 | }
21 |
22 | function setCollectionName(name) {
23 | collectionName = name;
24 | }
25 |
26 | function emitChange() {
27 | CollectionStore.emit(CHANGE_EVENT);
28 | }
29 |
30 | var CollectionStore = assign({}, EventEmitter.prototype, {
31 |
32 | addChangeListener: function (callback) {
33 | this.on(CHANGE_EVENT, callback);
34 | },
35 |
36 | removeChangeListener: function (callback) {
37 | this.removeListener(CHANGE_EVENT, callback);
38 | },
39 |
40 | getCollectionTweets: function () {
41 | return collectionTweets;
42 | },
43 |
44 | getCollectionName: function() {
45 | return collectionName;
46 | }
47 | });
48 |
49 | function handleAction(action) {
50 | switch (action.type) {
51 |
52 | case 'add_tweet_to_collection':
53 | addTweetToCollection(action.tweet);
54 | emitChange();
55 | break;
56 |
57 | case 'remove_tweet_from_collection':
58 | removeTweetFromCollection(action.tweetId);
59 | emitChange();
60 | break;
61 |
62 | case 'remove_all_tweets_from_collection':
63 | removeAllTweetsFromCollection();
64 | emitChange();
65 | break;
66 |
67 | case 'set_collection_name':
68 | setCollectionName(action.collectionName);
69 | emitChange();
70 | break;
71 |
72 | default: // ... do nothing
73 | }
74 | }
75 |
76 | CollectionStore.dispatchToken = AppDispatcher.register(handleAction);
77 |
78 | module.exports = CollectionStore;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/Collection.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 | var CollectionControls = require('./CollectionControls.react');
4 | var TweetList = require('./TweetList.react');
5 | var Header = require('./Header.react');
6 | var CollectionUtils = require('../utils/CollectionUtils');
7 | var CollectionStore = require('../stores/CollectionStore');
8 |
9 | var Collection = React.createClass({
10 |
11 | getInitialState: function () {
12 | return {
13 | collectionTweets: CollectionStore.getCollectionTweets()
14 | }
15 | },
16 |
17 | componentDidMount: function () {
18 | CollectionStore.addChangeListener(this.onCollectionChange);
19 | },
20 |
21 | componentWillUnmount: function () {
22 | CollectionStore.removeChangeListener(this.onCollectionChange);
23 | },
24 |
25 | onCollectionChange: function () {
26 | this.setState({
27 | collectionTweets: CollectionStore.getCollectionTweets()
28 | });
29 | },
30 |
31 | createHtmlMarkupStringOfTweetList: function () {
32 | var htmlString = ReactDOMServer.renderToStaticMarkup(
33 |
34 | );
35 |
36 | var htmlMarkup = {
37 | html: htmlString
38 | };
39 |
40 | return JSON.stringify(htmlMarkup);
41 | },
42 |
43 | render: function () {
44 | var collectionTweets = this.state.collectionTweets;
45 | var numberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweets);
46 | var htmlMarkup;
47 |
48 | if (numberOfTweetsInCollection > 0) {
49 | htmlMarkup = this.createHtmlMarkupStringOfTweetList();
50 |
51 | return (
52 |
53 |
56 |
57 |
58 |
59 | );
60 | }
61 |
62 | return ;
63 | }
64 | });
65 |
66 | module.exports = Collection;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/CollectionControls.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Header = require('./Header.react');
3 | var Button = require('./Button.react');
4 | var CollectionRenameForm = require('./CollectionRenameForm.react');
5 | var CollectionExportForm = require('./CollectionExportForm.react');
6 | var CollectionActionCreators = require('../actions/CollectionActionCreators');
7 | var CollectionStore = require('../stores/CollectionStore');
8 |
9 | var CollectionControls = React.createClass({
10 |
11 | getInitialState: function () {
12 | return {
13 | isEditingName: false
14 | };
15 | },
16 |
17 | getHeaderText: function () {
18 | var numberOfTweetsInCollection = this.props.numberOfTweetsInCollection;
19 | var text = numberOfTweetsInCollection;
20 | var name = CollectionStore.getCollectionName();
21 |
22 | if (numberOfTweetsInCollection === 1) {
23 | text = text + ' tweet in your';
24 | } else {
25 | text = text + ' tweets in your';
26 | }
27 |
28 | return (
29 |
30 | {text} {name} collection
31 |
32 | );
33 | },
34 |
35 | toggleEditCollectionName: function () {
36 | this.setState({
37 | isEditingName: !this.state.isEditingName
38 | });
39 | },
40 |
41 | removeAllTweetsFromCollection: function () {
42 | CollectionActionCreators.removeAllTweetsFromCollection();
43 | },
44 |
45 | render: function () {
46 | if (this.state.isEditingName) {
47 | return (
48 |
49 | );
50 | }
51 |
52 | return (
53 |
54 |
55 |
58 |
59 |
62 |
63 |
64 |
65 | );
66 | }
67 | });
68 |
69 | module.exports = CollectionControls;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/CollectionControls.react.js:
--------------------------------------------------------------------------------
1 |
2 | var React = require('react');
3 | var Header = require('./Header.react');
4 | var Button = require('./Button.react');
5 | var CollectionRenameForm = require('./CollectionRenameForm.react');
6 | var CollectionExportForm = require('./CollectionExportForm.react');
7 |
8 | var CollectionControls = React.createClass({
9 |
10 | getInitialState: function () {
11 | return {
12 | name: 'new',
13 | isEditingName: false
14 | };
15 | },
16 |
17 | getHeaderText: function () {
18 | var numberOfTweetsInCollection = this.props.numberOfTweetsInCollection;
19 | var text = numberOfTweetsInCollection;
20 |
21 | if (numberOfTweetsInCollection === 1) {
22 | text = text + ' tweet in your';
23 | } else {
24 | text = text + ' tweets in your';
25 | }
26 |
27 | return (
28 |
29 | {text} {this.state.name} collection
30 |
31 | );
32 | },
33 |
34 | toggleEditCollectionName: function () {
35 | this.setState({
36 | isEditingName: !this.state.isEditingName
37 | });
38 | },
39 |
40 | setCollectionName: function (name) {
41 | this.setState({
42 | name: name,
43 | isEditingName: false
44 | });
45 | },
46 |
47 | render: function () {
48 | if (this.state.isEditingName) {
49 | return (
50 |
54 | );
55 | }
56 |
57 | return (
58 |
59 |
60 |
61 |
64 |
65 |
68 |
69 |
70 |
71 | );
72 | }
73 | });
74 |
75 | module.exports = CollectionControls;
76 |
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/CollectionControls.react.js:
--------------------------------------------------------------------------------
1 |
2 | var React = require('react');
3 | var Header = require('./Header.react');
4 | var Button = require('./Button.react');
5 | var CollectionRenameForm = require('./CollectionRenameForm.react');
6 | var CollectionExportForm = require('./CollectionExportForm.react');
7 |
8 | var CollectionControls = React.createClass({
9 |
10 | getInitialState: function () {
11 | return {
12 | name: 'new',
13 | isEditingName: false
14 | };
15 | },
16 |
17 | getHeaderText: function () {
18 | var numberOfTweetsInCollection = this.props.numberOfTweetsInCollection;
19 | var text = numberOfTweetsInCollection;
20 |
21 | if (numberOfTweetsInCollection === 1) {
22 | text = text + ' tweet in your';
23 | } else {
24 | text = text + ' tweets in your';
25 | }
26 |
27 | return (
28 |
29 | {text} {this.state.name} collection
30 |
31 | );
32 | },
33 |
34 | toggleEditCollectionName: function () {
35 | this.setState({
36 | isEditingName: !this.state.isEditingName
37 | });
38 | },
39 |
40 | setCollectionName: function (name) {
41 | this.setState({
42 | name: name,
43 | isEditingName: false
44 | });
45 | },
46 |
47 | render: function () {
48 | if (this.state.isEditingName) {
49 | return (
50 |
54 | );
55 | }
56 |
57 | return (
58 |
59 |
60 |
61 |
64 |
65 |
68 |
69 |
70 |
71 | );
72 | }
73 | });
74 |
75 | module.exports = CollectionControls;
76 |
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/CollectionControls.react.js:
--------------------------------------------------------------------------------
1 |
2 | var React = require('react');
3 | var Header = require('./Header.react');
4 | var Button = require('./Button.react');
5 | var CollectionRenameForm = require('./CollectionRenameForm.react');
6 | var CollectionExportForm = require('./CollectionExportForm.react');
7 |
8 | var CollectionControls = React.createClass({
9 |
10 | getInitialState: function () {
11 | return {
12 | name: 'new',
13 | isEditingName: false
14 | };
15 | },
16 |
17 | getHeaderText: function () {
18 | var numberOfTweetsInCollection = this.props.numberOfTweetsInCollection;
19 | var text = numberOfTweetsInCollection;
20 |
21 | if (numberOfTweetsInCollection === 1) {
22 | text = text + ' tweet in your';
23 | } else {
24 | text = text + ' tweets in your';
25 | }
26 |
27 | return (
28 |
29 | {text} {this.state.name} collection
30 |
31 | );
32 | },
33 |
34 | toggleEditCollectionName: function () {
35 | this.setState({
36 | isEditingName: !this.state.isEditingName
37 | });
38 | },
39 |
40 | setCollectionName: function (name) {
41 | this.setState({
42 | name: name,
43 | isEditingName: false
44 | });
45 | },
46 |
47 | render: function () {
48 | if (this.state.isEditingName) {
49 | return (
50 |
54 | );
55 | }
56 |
57 | return (
58 |
59 |
60 |
61 |
64 |
65 |
68 |
69 |
70 |
71 | );
72 | }
73 | });
74 |
75 | module.exports = CollectionControls;
76 |
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/CollectionRenameForm.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Header = require('./Header.react');
3 | var Button = require('./Button.react');
4 | var CollectionActionCreators = require('../actions/CollectionActionCreators');
5 | var CollectionStore = require('../stores/CollectionStore');
6 |
7 | var inputStyle = {
8 | marginRight: '5px'
9 | };
10 |
11 | var CollectionRenameForm = React.createClass({
12 |
13 | getInitialState: function() {
14 | return {
15 | inputValue: CollectionStore.getCollectionName()
16 | };
17 | },
18 |
19 | setInputValue: function (inputValue) {
20 | this.setState({
21 | inputValue: inputValue
22 | });
23 | },
24 |
25 | handleInputValueChange: function (event) {
26 | var inputValue = event.target.value;
27 | this.setInputValue(inputValue);
28 | },
29 |
30 | handleFormSubmit: function (event) {
31 | event.preventDefault();
32 |
33 | var collectionName = this.state.inputValue;
34 |
35 | CollectionActionCreators.setCollectionName(collectionName);
36 | this.props.onCancelCollectionNameChange();
37 | },
38 |
39 | handleFormCancel: function (event) {
40 | event.preventDefault();
41 |
42 | var collectionName = CollectionStore.getCollectionName();
43 | this.setInputValue(collectionName);
44 | this.props.onCancelCollectionNameChange();
45 | },
46 |
47 | componentDidMount: function () {
48 | this.refs.collectionName.focus();
49 | },
50 |
51 | render: function () {
52 | return (
53 |
68 | );
69 | }
70 | });
71 |
72 | module.exports = CollectionRenameForm;
--------------------------------------------------------------------------------
/code/chapter06/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 |
6 | var StreamTweet = React.createClass({
7 |
8 | getInitialState: function () {
9 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
10 |
11 | return {
12 | numberOfCharactersIsIncreasing: null,
13 | headerText: null
14 | };
15 | },
16 |
17 | componentWillMount: function () {
18 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
19 |
20 | this.setState({
21 | numberOfCharactersIsIncreasing: true,
22 | headerText: 'Latest public photo from Twitter'
23 | });
24 |
25 | window.snapterest = {
26 | numberOfReceivedTweets: 1,
27 | numberOfDisplayedTweets: 1
28 | };
29 | },
30 |
31 | componentDidMount: function () {
32 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
33 |
34 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
35 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
36 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
37 | },
38 |
39 | componentWillReceiveProps: function (nextProps) {
40 | console.log('[Snapterest] StreamTweet: 4. Running componentWillReceiveProps()');
41 |
42 | var currentTweetLength = this.props.tweet.text.length;
43 | var nextTweetLength = nextProps.tweet.text.length;
44 | var isNumberOfCharactersIncreasing = (nextTweetLength > currentTweetLength);
45 | var headerText;
46 |
47 | this.setState({
48 | numberOfCharactersIsIncreasing: isNumberOfCharactersIncreasing
49 | });
50 |
51 | if (isNumberOfCharactersIncreasing) {
52 | headerText = 'Number of characters is increasing';
53 | } else {
54 | headerText = 'Latest public photo from Twitter';
55 | }
56 |
57 | this.setState({
58 | headerText: headerText
59 | });
60 |
61 | window.snapterest.numberOfReceivedTweets++;
62 | },
63 |
64 | shouldComponentUpdate: function (nextProps, nextState) {
65 | console.log('[Snapterest] StreamTweet: 5. Running shouldComponentUpdate()');
66 |
67 | return (nextProps.tweet.text.length > 1);
68 | },
69 |
70 | componentWillUpdate: function (nextProps, nextState) {
71 | console.log('[Snapterest] StreamTweet: 6. Running componentWillUpdate()');
72 | },
73 |
74 | componentDidUpdate: function (prevProps, prevState) {
75 | console.log('[Snapterest] StreamTweet: 7. Running componentDidUpdate()');
76 |
77 | window.snapterest.numberOfDisplayedTweets++;
78 | },
79 |
80 | componentWillUnmount: function () {
81 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
82 |
83 | delete window.snapterest;
84 | },
85 |
86 | render: function () {
87 | console.log('[Snapterest] StreamTweet: Running render()');
88 |
89 | return (
90 |
96 | );
97 | }
98 | });
99 |
100 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/code/chapter07/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 |
6 | var StreamTweet = React.createClass({
7 |
8 | getInitialState: function () {
9 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
10 |
11 | return {
12 | numberOfCharactersIsIncreasing: null,
13 | headerText: null
14 | };
15 | },
16 |
17 | componentWillMount: function () {
18 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
19 |
20 | this.setState({
21 | numberOfCharactersIsIncreasing: true,
22 | headerText: 'Latest public photo from Twitter'
23 | });
24 |
25 | window.snapterest = {
26 | numberOfReceivedTweets: 1,
27 | numberOfDisplayedTweets: 1
28 | };
29 | },
30 |
31 | componentDidMount: function () {
32 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
33 |
34 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
35 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
36 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
37 | },
38 |
39 | componentWillReceiveProps: function (nextProps) {
40 | console.log('[Snapterest] StreamTweet: 4. Running componentWillReceiveProps()');
41 |
42 | var currentTweetLength = this.props.tweet.text.length;
43 | var nextTweetLength = nextProps.tweet.text.length;
44 | var isNumberOfCharactersIncreasing = (nextTweetLength > currentTweetLength);
45 | var headerText;
46 |
47 | this.setState({
48 | numberOfCharactersIsIncreasing: isNumberOfCharactersIncreasing
49 | });
50 |
51 | if (isNumberOfCharactersIncreasing) {
52 | headerText = 'Number of characters is increasing';
53 | } else {
54 | headerText = 'Latest public photo from Twitter';
55 | }
56 |
57 | this.setState({
58 | headerText: headerText
59 | });
60 |
61 | window.snapterest.numberOfReceivedTweets++;
62 | },
63 |
64 | shouldComponentUpdate: function (nextProps, nextState) {
65 | console.log('[Snapterest] StreamTweet: 5. Running shouldComponentUpdate()');
66 |
67 | return (nextProps.tweet.text.length > 1);
68 | },
69 |
70 | componentWillUpdate: function (nextProps, nextState) {
71 | console.log('[Snapterest] StreamTweet: 6. Running componentWillUpdate()');
72 | },
73 |
74 | componentDidUpdate: function (prevProps, prevState) {
75 | console.log('[Snapterest] StreamTweet: 7. Running componentDidUpdate()');
76 |
77 | window.snapterest.numberOfDisplayedTweets++;
78 | },
79 |
80 | componentWillUnmount: function () {
81 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
82 |
83 | delete window.snapterest;
84 | },
85 |
86 | render: function () {
87 | console.log('[Snapterest] StreamTweet: Running render()');
88 |
89 | return (
90 |
96 | );
97 | }
98 | });
99 |
100 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/code/chapter08/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 |
6 | var StreamTweet = React.createClass({
7 |
8 | getInitialState: function () {
9 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
10 |
11 | return {
12 | numberOfCharactersIsIncreasing: null,
13 | headerText: null
14 | };
15 | },
16 |
17 | componentWillMount: function () {
18 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
19 |
20 | this.setState({
21 | numberOfCharactersIsIncreasing: true,
22 | headerText: 'Latest public photo from Twitter'
23 | });
24 |
25 | window.snapterest = {
26 | numberOfReceivedTweets: 1,
27 | numberOfDisplayedTweets: 1
28 | };
29 | },
30 |
31 | componentDidMount: function () {
32 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
33 |
34 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
35 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
36 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
37 | },
38 |
39 | componentWillReceiveProps: function (nextProps) {
40 | console.log('[Snapterest] StreamTweet: 4. Running componentWillReceiveProps()');
41 |
42 | var currentTweetLength = this.props.tweet.text.length;
43 | var nextTweetLength = nextProps.tweet.text.length;
44 | var isNumberOfCharactersIncreasing = (nextTweetLength > currentTweetLength);
45 | var headerText;
46 |
47 | this.setState({
48 | numberOfCharactersIsIncreasing: isNumberOfCharactersIncreasing
49 | });
50 |
51 | if (isNumberOfCharactersIncreasing) {
52 | headerText = 'Number of characters is increasing';
53 | } else {
54 | headerText = 'Latest public photo from Twitter';
55 | }
56 |
57 | this.setState({
58 | headerText: headerText
59 | });
60 |
61 | window.snapterest.numberOfReceivedTweets++;
62 | },
63 |
64 | shouldComponentUpdate: function (nextProps, nextState) {
65 | console.log('[Snapterest] StreamTweet: 5. Running shouldComponentUpdate()');
66 |
67 | return (nextProps.tweet.text.length > 1);
68 | },
69 |
70 | componentWillUpdate: function (nextProps, nextState) {
71 | console.log('[Snapterest] StreamTweet: 6. Running componentWillUpdate()');
72 | },
73 |
74 | componentDidUpdate: function (prevProps, prevState) {
75 | console.log('[Snapterest] StreamTweet: 7. Running componentDidUpdate()');
76 |
77 | window.snapterest.numberOfDisplayedTweets++;
78 | },
79 |
80 | componentWillUnmount: function () {
81 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
82 |
83 | delete window.snapterest;
84 | },
85 |
86 | render: function () {
87 | console.log('[Snapterest] StreamTweet: Running render()');
88 |
89 | return (
90 |
96 | );
97 | }
98 | });
99 |
100 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/code/chapter09/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 |
6 | var StreamTweet = React.createClass({
7 |
8 | getInitialState: function () {
9 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
10 |
11 | return {
12 | numberOfCharactersIsIncreasing: null,
13 | headerText: null
14 | };
15 | },
16 |
17 | componentWillMount: function () {
18 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
19 |
20 | this.setState({
21 | numberOfCharactersIsIncreasing: true,
22 | headerText: 'Latest public photo from Twitter'
23 | });
24 |
25 | window.snapterest = {
26 | numberOfReceivedTweets: 1,
27 | numberOfDisplayedTweets: 1
28 | };
29 | },
30 |
31 | componentDidMount: function () {
32 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
33 |
34 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
35 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
36 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
37 | },
38 |
39 | componentWillReceiveProps: function (nextProps) {
40 | console.log('[Snapterest] StreamTweet: 4. Running componentWillReceiveProps()');
41 |
42 | var currentTweetLength = this.props.tweet.text.length;
43 | var nextTweetLength = nextProps.tweet.text.length;
44 | var isNumberOfCharactersIncreasing = (nextTweetLength > currentTweetLength);
45 | var headerText;
46 |
47 | this.setState({
48 | numberOfCharactersIsIncreasing: isNumberOfCharactersIncreasing
49 | });
50 |
51 | if (isNumberOfCharactersIncreasing) {
52 | headerText = 'Number of characters is increasing';
53 | } else {
54 | headerText = 'Latest public photo from Twitter';
55 | }
56 |
57 | this.setState({
58 | headerText: headerText
59 | });
60 |
61 | window.snapterest.numberOfReceivedTweets++;
62 | },
63 |
64 | shouldComponentUpdate: function (nextProps, nextState) {
65 | console.log('[Snapterest] StreamTweet: 5. Running shouldComponentUpdate()');
66 |
67 | return (nextProps.tweet.text.length > 1);
68 | },
69 |
70 | componentWillUpdate: function (nextProps, nextState) {
71 | console.log('[Snapterest] StreamTweet: 6. Running componentWillUpdate()');
72 | },
73 |
74 | componentDidUpdate: function (prevProps, prevState) {
75 | console.log('[Snapterest] StreamTweet: 7. Running componentDidUpdate()');
76 |
77 | window.snapterest.numberOfDisplayedTweets++;
78 | },
79 |
80 | componentWillUnmount: function () {
81 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
82 |
83 | delete window.snapterest;
84 | },
85 |
86 | render: function () {
87 | console.log('[Snapterest] StreamTweet: Running render()');
88 |
89 | return (
90 |
96 | );
97 | }
98 | });
99 |
100 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/code/chapter10/snapterest/source/components/StreamTweet.react.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var Header = require('./Header.react');
4 | var Tweet = require('./Tweet.react');
5 | var CollectionActionCreators = require('../actions/CollectionActionCreators');
6 |
7 | var StreamTweet = React.createClass({
8 |
9 | getInitialState: function () {
10 | console.log('[Snapterest] StreamTweet: 1. Running getInitialState()');
11 |
12 | return {
13 | numberOfCharactersIsIncreasing: null,
14 | headerText: null
15 | };
16 | },
17 |
18 | addTweetToCollection: function (tweet) {
19 | CollectionActionCreators.addTweetToCollection(tweet);
20 | },
21 |
22 | componentWillMount: function () {
23 | console.log('[Snapterest] StreamTweet: 2. Running componentWillMount()');
24 |
25 | this.setState({
26 | numberOfCharactersIsIncreasing: true,
27 | headerText: 'Latest public photo from Twitter'
28 | });
29 |
30 | window.snapterest = {
31 | numberOfReceivedTweets: 1,
32 | numberOfDisplayedTweets: 1
33 | };
34 | },
35 |
36 | componentDidMount: function () {
37 | console.log('[Snapterest] StreamTweet: 3. Running componentDidMount()');
38 |
39 | var componentDOMRepresentation = ReactDOM.findDOMNode(this);
40 | window.snapterest.headerHtml = componentDOMRepresentation.children[0].outerHTML;
41 | window.snapterest.tweetHtml = componentDOMRepresentation.children[1].outerHTML;
42 | },
43 |
44 | componentWillReceiveProps: function (nextProps) {
45 | console.log('[Snapterest] StreamTweet: 4. Running componentWillReceiveProps()');
46 |
47 | var currentTweetLength = this.props.tweet.text.length;
48 | var nextTweetLength = nextProps.tweet.text.length;
49 | var isNumberOfCharactersIncreasing = (nextTweetLength > currentTweetLength);
50 | var headerText;
51 |
52 | this.setState({
53 | numberOfCharactersIsIncreasing: isNumberOfCharactersIncreasing
54 | });
55 |
56 | if (isNumberOfCharactersIncreasing) {
57 | headerText = 'Number of characters is increasing';
58 | } else {
59 | headerText = 'Latest public photo from Twitter';
60 | }
61 |
62 | this.setState({
63 | headerText: headerText
64 | });
65 |
66 | window.snapterest.numberOfReceivedTweets++;
67 | },
68 |
69 | shouldComponentUpdate: function (nextProps, nextState) {
70 | console.log('[Snapterest] StreamTweet: 5. Running shouldComponentUpdate()');
71 |
72 | return (nextProps.tweet.text.length > 1);
73 | },
74 |
75 | componentWillUpdate: function (nextProps, nextState) {
76 | console.log('[Snapterest] StreamTweet: 6. Running componentWillUpdate()');
77 | },
78 |
79 | componentDidUpdate: function (prevProps, prevState) {
80 | console.log('[Snapterest] StreamTweet: 7. Running componentDidUpdate()');
81 |
82 | window.snapterest.numberOfDisplayedTweets++;
83 | },
84 |
85 | componentWillUnmount: function () {
86 | console.log('[Snapterest] StreamTweet: 8. Running componentWillUnmount()');
87 |
88 | delete window.snapterest;
89 | },
90 |
91 | render: function () {
92 | console.log('[Snapterest] StreamTweet: Running render()');
93 |
94 | return (
95 |
99 | );
100 | }
101 | });
102 |
103 | module.exports = StreamTweet;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # React.js Essentials
4 |
5 | Have you read [React.js Essentials](https://www.packtpub.com/web-development/reactjs-essentials) book yet? Share your comments, questions, ideas, thoughts.
6 |
7 | + [Source code](./code)
8 | + [Updates](./updates.md)
9 | + [Book's Project](https://github.com/fedosejev/react-essentials-project)
10 |
11 | Throughout the book you will be building a React.js app called Snapterest. Here is live version of Snapterest: http://fedosejev.github.io/react-essentials-project/
12 |
13 | ### Join our Facebook Page
14 |
15 | https://www.facebook.com/groups/ReactEssentials/
16 |
17 | ### I would really appreciate your help
18 |
19 | Can you please write a short review for the book on Amazon? Thank you!
20 |
21 | ### Where to get your copy?
22 |
23 | + [Amazon US](http://www.amazon.com/React-js-Essentials-Artemij-Fedosejev/dp/1783551623/)
24 | + [Amazon UK](http://www.amazon.co.uk/books/dp/1783551623)
25 | + [Amazon AU](http://www.amazon.com.au/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
26 | + [Amazon CA](http://www.amazon.ca/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
27 | + [Amazon ES](http://www.amazon.es/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
28 | + [Amazon IN](http://www.amazon.in/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
29 | + [Amazon JP](http://www.amazon.co.jp/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
30 | + [Amazon BR](http://www.amazon.com.br/React-js-Essentials-Artemij-Fedosejev-ebook/dp/B00YSILZRW)
31 | + [Packt Publishing](https://www.packtpub.com/web-development/reactjs-essentials)
32 | + [Google Play](https://play.google.com/store/books/details/Artemij_Fedosejev_React_js_Essentials?id=Rhl1CgAAQBAJ)
33 | + [iTunes](https://itunes.apple.com/us/book/react.js-essentials/id1028205748)
34 | + [PacktLiB](https://www.packtpub.com/packtlib/book/Web%20Development/9781783551620)
35 | + [Google Books](https://books.google.co.uk/books?id=Rhl1CgAAQBAJ&pg=PA20&dq=react+essentials&hl=en&sa=X&redir_esc=y#v=onepage&q=react%20essentials&f=false)
36 | + [O'Reilly Media](http://shop.oreilly.com/product/9781783551620.do)
37 | + [Waterstones](https://www.waterstones.com/book/react-js-essentials/artemij-fedosejev/9781783551620)
38 | + [Safari Books Online](https://www.safaribooksonline.com/library/view/reactjs-essentials/9781783551620/)
39 | + [Indigo](https://www.chapters.indigo.ca/en-ca/books/react-js-essentials/9781783551620-item.html)
40 | + [eBay UK](http://www.ebay.co.uk/itm/React-js-Essentials-by-Artemij-Fedosejev-/252142933077)
41 |
42 | ## Q/A
43 |
44 | Ask me any question on [Snapchat](https://www.snapchat.com) - my username is `artemij`.
45 |
46 | #### I get `SyntaxError: .../app.js: Unexpected token` when I run `gulp` command. What should I do?
47 |
48 | This is due to some breaking changes made in `babelify` version 7. The book uses `babelify` version __6__ - if you choose to use version 6 as well then please [do the following](https://github.com/fedosejev/react-essentials/blob/master/updates.md#chapter-1-page-14).
49 |
50 | If you choose to use `babelify` version __7__, then please see [this comment](https://github.com/fedosejev/react-essentials/issues/21#issuecomment-160316774).
51 |
52 | #### Can I have ES6 version of Snapterest?
53 |
54 | Yes! [Here it is](https://github.com/jmrog/react-essentials-es6-version). Special thanks to [Jason Rogers](https://github.com/jmrog) who converted Snapterest to ES6 syntax!
55 |
56 | #### Can I see Snapterest in action?
57 |
58 | Yes! http://fedosejev.github.io/react-essentials-project/
59 |
60 | #### How to deploy a stand alone React.js application described in the book?
61 |
62 | You can [deploy it on GitHub Pages](how-to-deploy.md).
63 |
64 | #### Have you seen your book on Reddit?
65 |
66 | [Yes](https://www.reddit.com/r/illegaltorrents/comments/3p008z/request_reactjs_essentials_by_artemij_fedosejev/).
67 |
68 | #### Can I have another example of using React.js with Flux?
69 |
70 | Sure, check my [Shopping List](https://github.com/fedosejev/shopping-list-react) example.
71 |
72 | ## Questions, errors, ideas or thoughts?
73 |
74 | Check [updates](./updates.md) or create a [new issue](https://github.com/fedosejev/react-essentials/issues).
75 |
76 | ## Superheroes
77 |
78 | Special thanks to [@magomimmo](https://github.com/magomimmo), [@ttanzer](https://github.com/ttanzer), [@rickhaffey](https://github.com/rickhaffey), [@RenatKunafin](https://github.com/RenatKunafin), [@blitzd](https://github.com/blitzd), [@duanec](https://github.com/duanec), [@gerturo](https://github.com/gerturo) who helped other readers to solve [various issues](https://github.com/fedosejev/react-essentials/issues)!
79 |
80 | ## Author
81 |
82 |
83 |
84 | Artemij Fedosejev is a technical lead living in London, United Kingdom. He is a self-taught web developer who has been a web developer since the early 2000s. Artemij earned his BSc in Computer Science from University College Cork, Ireland. He participated in the IGNITE Graduate Business Innovation Programme, where he built and launched a website that received the Most Innovative Project award.
85 |
86 | After graduation, Artemij moved to London to help local start-up companies build their products. He worked with JavaScript, Node.js, HTML5, CSS3, and other modern web technologies. After gaining some experience in the start-up industry, Artemij was presented with an opportunity to join Imperial College, London, work on a research and development, project and take leadership in creating frontends for a couple of web applications in the public health space. He played a key role in creating frontend architecture using React.js and Flux for [WGSA.net](http://wgsa.net) and [Microreact.org](http://microreact.org).
87 |
88 | + Website
89 | + LinkedIn
90 | + Twitter
91 | + Facebook
92 | + I answer your questions on Snapchat:
93 |
94 |
95 |
96 | ## Thank you
97 |
98 | This book is written for you and I appreciate so much for you investing your time, money and effort into reading this book.
99 |
100 | Keep learning and growing!
101 |
102 | Artemij
103 |
104 | artemij.github@gmail.com
105 |
--------------------------------------------------------------------------------