├── .gitignore
├── LICENSE
├── README.md
├── ch2
├── 2-1.json
├── 2-10.html
├── 2-11.html
├── 2-2.html
├── 2-3.html
├── 2-4.html
├── 2-5.html
├── 2-6.html
├── 2-7.html
├── 2-8.html
└── 2-9.html
├── ch3
├── 3-1.js
├── 3-2.js
├── 3-3.js
├── 3-4.js
├── 3-5.js
├── 3-6.js
├── 3-7.js
└── 3-8.js
├── ch4
├── 4-1.js
├── 4-10.js
├── 4-11.js
├── 4-12.js
├── 4-13.js
├── 4-2.js
├── 4-3.js
├── 4-4.js
├── 4-5.js
├── 4-6.js
├── 4-7.js
├── 4-8.js
└── 4-9.js
└── ch5
└── 5-1.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 React in Action
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # code
2 | Code listings for React in Action
3 |
--------------------------------------------------------------------------------
/ch2/2-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 123,
3 | "content": "What we hope ever to do with ease, we must first learn to do with diligence. — Samuel Johnson",
4 | "user": "Mark Thomas",
5 | "comments": [{
6 | "id": 0,
7 | "user": "David",
8 | "content": "such. win."
9 | }, {
10 | "id": 1,
11 | "user": "Peter",
12 | "content": "Who was Samuel Johnson?"
13 | }, {
14 | "id": 2,
15 | "user": "Mitchell",
16 | "content": "@Peter get off Letters and do your homework!"
17 | }, {
18 | "id": 3,
19 | "user": "Peter",
20 | "content": "@mitchell ok dad :P"
21 | }]
22 | }
23 |
--------------------------------------------------------------------------------
/ch2/2-10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React In Action
6 |
7 |
8 |
9 |
10 |
11 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/ch2/2-11.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React In Action
6 |
7 |
8 |
9 |
10 |
11 |
12 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/ch2/2-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React In Action
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ch2/2-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ch2/2-4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ch2/2-5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/ch2/2-6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ch2/2-7.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/ch2/2-8.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/ch2/2-9.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React In Action
7 |
8 |
9 |
10 |
11 |
12 |
13 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/ch3/3-1.js:
--------------------------------------------------------------------------------
1 | const letters = 'Letters';
2 | const splitLetters = letters.split('');
3 | console.log("Let's spell a word!");
4 | splitLetters.forEach(letter => console.log(letter));
5 |
--------------------------------------------------------------------------------
/ch3/3-2.js:
--------------------------------------------------------------------------------
1 | // `This` will refer to the global object
2 | console.log(Object.keys(this));
3 |
4 | // How many keys are there on the global object?
5 | console.log(Object.keys(window).length)
6 |
7 | // in node.js
8 | console.log(Object.keys(global).length)
9 |
--------------------------------------------------------------------------------
/ch3/3-3.js:
--------------------------------------------------------------------------------
1 | // when not logged in
2 | let user = null;
3 |
4 | // Load user data from somewhere using the new fetch API
5 | // (essentially the newer, better version of XMLHttpRequest)
6 |
7 | fetch(someUrl)
8 | .then(response => user = response.json())
9 | .catch(err => console.error(err));
10 |
11 | // when logged in
12 | console.log(user);
13 | // yields:
14 | // {
15 | // username: 'mark',
16 | // email: 'mark@ifelse.io'
17 | // firstName: 'Mark',
18 | // lastName: 'Thomas',
19 | // preferences: {
20 | // email: false,
21 | // react: true,
22 | // }
23 | // }
24 |
25 | // Change user settings; bring on the emails!
26 | user.preferences.email = true;
27 |
28 | // Update user settings
29 | application.updateUser(user);
30 |
31 | // Perform some logout action
32 | application.logout = function() {
33 | user = null
34 | };
35 |
36 | application.logout();
37 |
--------------------------------------------------------------------------------
/ch3/3-4.js:
--------------------------------------------------------------------------------
1 | const ShallowMerge = React.createClass({
2 | getInitialState: function() {
3 | return {
4 | user: {
5 | name: 'Mark',
6 | colors: {
7 | favorite: ''
8 | }
9 | }
10 | };
11 | },
12 | onButtonClick: function() {
13 | this.setState({
14 | user: {
15 | colors: {
16 | favorite: 'blue'
17 | }
18 | }
19 | });
20 | },
21 | render: function() {
22 | return (
23 |
24 |
My favorite color is {this.state.user.colors.favorite}
25 | and my name is
26 |
27 |
28 |
29 | )
30 | }
31 | })
32 |
33 | ReactDOM.render(
34 | ,
35 | document.getElementById('container')
36 | );
37 |
--------------------------------------------------------------------------------
/ch3/3-5.js:
--------------------------------------------------------------------------------
1 | const Counter = React.createClass({
2 | getInitialState: function() {
3 | return {
4 | count: 0
5 | };
6 | },
7 | onButtonClick: function() {
8 | this.setState(function(previousState, currentProps) {
9 | return {
10 | count: previousState.count + currentProps.incrementBy
11 | };
12 | });
13 | },
14 | render: function() {
15 | return (
16 |
17 |
{this.state.count}
18 |
19 |
20 | )
21 | }
22 | })
23 |
24 | ReactDOM.render(
25 | ,
26 | document.getElementById('container')
27 | );
28 |
--------------------------------------------------------------------------------
/ch3/3-6.js:
--------------------------------------------------------------------------------
1 | const Counter = React.createClass({
2 | propTypes: {
3 | incrementBy: React.PropTypes.number,
4 | name: React.PropTypes.string,
5 | counterStyle: React.PropTypes.shape({
6 | color: React.PropTypes.string,
7 | fontSize: React.PropTypes.number
8 | }),
9 | onIncrement: React.PropTypes.func.isRequired,
10 |
11 | },
12 | getDefaultProps: function() {
13 | return {incrementBy: 1};
14 | },
15 | getInitialState: function() {
16 | return {count: 0}
17 | },
18 | onButtonClick: function() {
19 | this.setState(function(previousState, currentProps) {
20 | return {
21 | count: previousState.count + currentProps.incrementBy
22 | };
23 | });
24 | },
25 | render: function() {
26 | // this.props.incrementBy = 2;
27 | return (
28 |
29 |
{this.state.count}
30 |
31 |
32 | )
33 | }
34 | })
35 |
36 | ReactDOM.render(
37 | ,
38 | document.getElementById('container')
39 | );
40 |
--------------------------------------------------------------------------------
/ch3/3-7.js:
--------------------------------------------------------------------------------
1 | function Greeting(props) {
2 | return Hello {props.for}!
;
3 | }
4 |
5 | Greeting.propTypes = {
6 | for: React.PropTypes.string.isRequired
7 | };
8 |
9 | Greeting.defaultProps = {
10 | for: 'hi'
11 | };
12 |
13 | ReactDOM.render(, mountNode);
14 |
15 | // Or using the ES6 arrow syntax
16 |
17 | const Greeting = (props) => Hello {props.for}
;
18 | //... specify props and default props same as above
19 |
20 | ReactDOM.render(, mountNode);
21 |
--------------------------------------------------------------------------------
/ch3/3-8.js:
--------------------------------------------------------------------------------
1 | const UserProfile = (props) => {
2 | return (
);
3 | };
4 | UserProfile.propTypes = {
5 | pagename: React.PropTypes.string
6 | };
7 |
8 | UserProfile.defaultProps = {
9 | pagename: 'Mark'
10 | };
11 |
12 | const UserProfileLink = (props) => {
13 | return (
14 |
15 | {this.props.username}
16 |
17 | );
18 | };
19 |
20 | const UserCard = (props) => {
21 | #C
22 | return (
23 |
24 |
25 |
26 |
27 | );
28 | };
29 |
30 | ReactDOM.render(
31 | ,
32 | document.getElementById('container')
33 | );
34 |
--------------------------------------------------------------------------------
/ch4/4-1.js:
--------------------------------------------------------------------------------
1 | const ChildComponent = React.createClass({
2 | render: function() {
3 | console.log('ChildComponent: render');
4 | return (
5 |
6 | Props: {this.props.name}
7 |
8 | );
9 | }
10 | });
11 |
12 | const ParentComponent = React.createClass({
13 | onInputChange: function(e) {
14 | this.setState({text: e.target.value});
15 | },
16 | render: function() {
17 | console.log('ParentComponent: render');
18 | return (
19 |
20 |
21 | Learn about rendering and lifecycle methods!
22 |
23 |
24 |
25 |
26 | );
27 | }
28 | });
29 |
30 | ReactDOM.render(, document.getElementById('container'));
31 |
--------------------------------------------------------------------------------
/ch4/4-10.js:
--------------------------------------------------------------------------------
1 | //…
2 | { this.state.loaded ? loaded!
:
not loaded
}
3 | //…
4 |
--------------------------------------------------------------------------------
/ch4/4-11.js:
--------------------------------------------------------------------------------
1 | // …
2 | render(){
3 | return (
4 |
5 | {
6 | this.state.loaded ?
7 | this.state.posts.map(post => {
8 | return (
9 |
10 | {post.content}
11 |
12 | );
13 | })
14 | :
15 |
16 | Loading!
17 |
18 | }
19 |
20 | );
21 | }
22 | //…
23 |
--------------------------------------------------------------------------------
/ch4/4-12.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const Post = (props) => {
4 | return (
5 |
6 |
7 | {post.content}
8 |
9 |
10 | );
11 | }
12 |
13 | Post.propTypes = {
14 | post: PropTypes.object.isRequired,
15 | }
16 |
--------------------------------------------------------------------------------
/ch4/4-13.js:
--------------------------------------------------------------------------------
1 | import Post from ‘./Post’;
2 | // ..
3 | render() {
4 | return (
5 |
6 | this.state.loaded ?
7 | state.posts.map(post =>
)
8 | :
9 | Loading!
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/ch4/4-2.js:
--------------------------------------------------------------------------------
1 | const ChildComponent = React.createClass({
2 | propTypes: {
3 | name: React.PropTypes.string
4 | },
5 | getInitialState: function() {
6 | console.log('ChildComponent: getInitialState');
7 | return {name: 'Mark'};
8 | },
9 | render: function() {
10 | console.log('ChildComponent: render');
11 | return (
12 |
13 | Props: {this.props.name}
14 |
15 | );
16 | }
17 | });
18 |
19 | const ParentComponent = React.createClass({
20 | getDefaultProps: function() {
21 | console.log('ParentComponent: getDefaultProps');
22 | },
23 | getInitialState: function() {
24 | console.log('ParentComponent: getInitialState');
25 | return {text: ''};
26 | },
27 | render: function() {
28 | console.log('ParentComponent: render');
29 | return (
30 |
31 |
Learn about rendering and lifecycle methods!
32 |
33 |
34 |
35 | );
36 | }
37 | });
38 |
39 | ReactDOM.render(
40 | ,
41 | document.getElementById('container')
42 | );
43 |
--------------------------------------------------------------------------------
/ch4/4-3.js:
--------------------------------------------------------------------------------
1 | const ParentComponent = React.createClass({
2 | getDefaultProps: function() {
3 | console.log('ParentComponent: getDefaultProps');
4 | },
5 | getInitialState: function() {
6 | console.log('ParentComponent: getInitialState');
7 | return {text: ''};
8 | },
9 | componentWillMount: function() {
10 | console.log('ParentComponent: componentWillMount');
11 | },
12 | componentDidMount: function() {
13 | console.log('ParentComponent: componentDidMount');
14 | },
15 | componentWillUnmount: function() {
16 | console.log('ParentComponent: componentWillUnmount');
17 | },
18 | onInputChange: function(e) {
19 | this.setState({text: e.target.value});
20 | },
21 | render: function() {
22 | console.log('ParentComponent: render');
23 | return (
24 |
25 |
Let's learn about rendering and lifecycle methods!
26 |
27 |
28 |
29 | );
30 | }
31 | });
32 |
--------------------------------------------------------------------------------
/ch4/4-4.js:
--------------------------------------------------------------------------------
1 | const ChildComponent = React.createClass({
2 | //...
3 | shouldComponentUpdate: function(nextProps, nextState) {
4 | console.log(' - shouldComponentUpdate()');
5 | console.log('nextProps: ', nextProps);
6 | console.log('nextnextState: ', nextState);
7 | return true;
8 | },
9 | componentWillUpdate: function(nextProps, nextState) {
10 | console.log(' - componentWillUpdate');
11 | console.log('nextProps: ', nextProps);
12 | console.log('nextState: ', nextState);
13 | },
14 | componentDidUpdate: function(previousProps, previousState) {
15 | console.log('ChildComponent: componentDidUpdate');
16 | console.log('previousProps:', previousProps);
17 | console.log('previousState:', previousState);
18 | },
19 | //...
20 | });
21 |
--------------------------------------------------------------------------------
/ch4/4-5.js:
--------------------------------------------------------------------------------
1 | // ChildComponent : getDefaultProps
2 | // ParentComponent - getDefaultProps
3 | // ParentComponent - getInitialState
4 | // ParentComponent - componentWillMount
5 | // ParentComponent - render
6 | // ChildComponent : componentWillMount
7 | // ChildComponent - render
8 | // ChildComponent : componentDidMount
9 | // ParentComponent - componentDidMount
10 | // ParentComponent - render
11 | // ChildComponent : componentWillReceiveProps()
12 | // Object {text: "Mark"} //A
13 | // - shouldComponentUpdate()
14 | // nextProps: Object {text: "Mark"}
15 | // nextnextState: Object {name: "Mark"}
16 | // - componentWillUpdate
17 | // nextProps: Object {text: "Mark"}
18 | // nextState: Object {name: "Mark"}
19 | // ChildComponent - render
20 | // ChildComponent - componentDidUpdate
21 | // previousProps: Object {text: ""}
22 | // previousState: Object {name: "Mark"}
23 |
--------------------------------------------------------------------------------
/ch4/4-6.js:
--------------------------------------------------------------------------------
1 | const ChildComponent = React.createClass({
2 | //...
3 | componentWillUnmount: function() {
4 | console.log('ChildComponent: componentWillUnmount');
5 | },
6 | //...
7 | render: function() {
8 | console.log('ChildComponent: render');
9 | return (
10 |
11 | Props: {this.props.name}
12 |
13 | );
14 | }
15 | });
16 |
17 | const ParentComponent = React.createClass({
18 | //...
19 | componentWillUnmount: function() {
20 | console.log('ParentComponent: componentWillUnmount');
21 | },
22 | //...
23 | render: function() {
24 | console.log('ParentComponent: render');
25 | return (
26 |
27 |
Learn about rendering and lifecycle methods!
28 |
29 |
30 |
31 | );
32 | }
33 | });
34 | //...
35 |
--------------------------------------------------------------------------------
/ch4/4-7.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export class App extends React.Component {
4 | constructor() {
5 | super();
6 | this.state = {
7 | posts: {
8 | all: [],
9 | filtered: []
10 | },
11 | category: null,
12 | filters: {
13 | image: null,
14 | link: null,
15 | categories: []
16 | },
17 | loaded: false,
18 | showBanner: false
19 | };
20 | }
21 |
22 | render() {
23 | return (
24 |
25 | Letters Social— coming soon!
26 |
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ch4/4-8.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import { App } from './components/app';
4 |
5 | render(, document.getElementById('app'));
6 |
--------------------------------------------------------------------------------
/ch4/4-9.js:
--------------------------------------------------------------------------------
1 | import fetch from 'isomorphic-fetch';
2 |
3 | // …
4 |
5 | componentDidMount() {
6 | fetch(‘http://localhost:3500/posts?_limit=25’)
7 | .then(res => res.json())
8 | .then(posts => {
9 | this.setState({
10 | posts: {
11 | posts,
12 | },
13 | loaded: true,
14 | });
15 | });
16 | }
17 | //…
18 |
--------------------------------------------------------------------------------
/ch5/5-1.js:
--------------------------------------------------------------------------------
1 | // Post schema
2 | class Post {
3 | comments: ?Array;
4 | content: string;
5 | date: Date;
6 | id: string;
7 | image: ?string;
8 | link: ?Object;
9 | user: ?Object;
10 | likes: number;
11 | categories: Array;
12 | }
13 |
--------------------------------------------------------------------------------