├── .babelrc ├── .eslintrc ├── .gitignore ├── README.md ├── index.html ├── package.json ├── src ├── actions │ ├── index.js │ └── itemsActions.js ├── app.js ├── components │ ├── colorizeWrapper.js │ ├── todoItem.e2e.spec.js │ ├── todoItem.js │ └── todoItem.spec.js ├── containers │ └── todoList.js ├── reducers │ ├── index.js │ └── itemsReducer.js ├── store │ └── configureStore.js └── testSetup.spec.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "experimentalObjectRestSpread": true, 5 | "jsx": true 6 | }, 7 | 8 | "env": { 9 | "browser": true, 10 | "es6": true, 11 | "node": true 12 | }, 13 | 14 | "plugins": [ 15 | "standard", 16 | "react" 17 | ], 18 | 19 | "globals": { 20 | "document": false, 21 | "navigator": false, 22 | "window": false, 23 | "expect": false, 24 | "sinon": false, 25 | "before": false, 26 | "after": false, 27 | "afterEach": false, 28 | "describe": false, 29 | "beforeEach": false, 30 | "inject": false, 31 | "it": false 32 | }, 33 | 34 | "rules": { 35 | "accessor-pairs": 2, 36 | "arrow-spacing": [2, { "before": true, "after": true }], 37 | "block-spacing": [2, "always"], 38 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 39 | "comma-dangle": [2, "never"], 40 | "comma-spacing": [2, { "before": false, "after": true }], 41 | "comma-style": [2, "last"], 42 | "constructor-super": 2, 43 | "curly": [2, "multi-line"], 44 | "dot-location": [2, "property"], 45 | "eol-last": 2, 46 | "eqeqeq": [2, "allow-null"], 47 | "generator-star-spacing": [2, { "before": true, "after": true }], 48 | "handle-callback-err": [2, "^(err|error)$" ], 49 | "indent": [2, 2, { "SwitchCase": 1 }], 50 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 51 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 52 | "new-parens": 2, 53 | "no-array-constructor": 2, 54 | "no-caller": 2, 55 | "no-class-assign": 2, 56 | "no-cond-assign": 2, 57 | "no-const-assign": 2, 58 | "no-control-regex": 2, 59 | "no-debugger": 2, 60 | "no-delete-var": 2, 61 | "no-dupe-args": 2, 62 | "no-dupe-class-members": 2, 63 | "no-dupe-keys": 2, 64 | "no-duplicate-case": 2, 65 | "no-empty-character-class": 2, 66 | "no-empty-label": 2, 67 | "no-eval": 2, 68 | "no-ex-assign": 2, 69 | "no-extend-native": 2, 70 | "no-extra-bind": 2, 71 | "no-extra-boolean-cast": 2, 72 | "no-extra-parens": [2, "functions"], 73 | "no-fallthrough": 2, 74 | "no-floating-decimal": 2, 75 | "no-func-assign": 2, 76 | "no-implied-eval": 2, 77 | "no-inner-declarations": [2, "functions"], 78 | "no-invalid-regexp": 2, 79 | "no-irregular-whitespace": 2, 80 | "no-iterator": 2, 81 | "no-label-var": 2, 82 | "no-labels": 2, 83 | "no-lone-blocks": 2, 84 | "no-mixed-spaces-and-tabs": 2, 85 | "no-multi-spaces": 2, 86 | "no-multi-str": 2, 87 | "no-multiple-empty-lines": [2, { "max": 1 }], 88 | "no-native-reassign": 2, 89 | "no-negated-in-lhs": 2, 90 | "no-new": 2, 91 | "no-new-func": 2, 92 | "no-new-object": 2, 93 | "no-new-require": 2, 94 | "no-new-wrappers": 2, 95 | "no-obj-calls": 2, 96 | "no-octal": 2, 97 | "no-octal-escape": 2, 98 | "no-proto": 2, 99 | "no-redeclare": 2, 100 | "no-regex-spaces": 2, 101 | "no-return-assign": 2, 102 | "no-self-compare": 2, 103 | "no-sequences": 2, 104 | "no-shadow-restricted-names": 2, 105 | "no-spaced-func": 2, 106 | "no-sparse-arrays": 2, 107 | "no-this-before-super": 2, 108 | "no-throw-literal": 2, 109 | "no-trailing-spaces": 2, 110 | "no-undef": 2, 111 | "no-undef-init": 2, 112 | "no-unexpected-multiline": 2, 113 | "no-unneeded-ternary": 2, 114 | "no-unreachable": 2, 115 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 116 | "no-useless-call": 2, 117 | "no-with": 2, 118 | "one-var": [2, { "initialized": "never" }], 119 | "operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }], 120 | "padded-blocks": [2, "never"], 121 | "quotes": [2, "single", "avoid-escape"], 122 | "radix": 2, 123 | "semi": [2, "never"], 124 | "space-after-keywords": [2, "always"], 125 | "space-before-blocks": [2, "always"], 126 | "space-before-function-paren": [2, "always"], 127 | "space-in-parens": [2, "never"], 128 | "space-infix-ops": 2, 129 | "space-return-throw-case": 2, 130 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 131 | "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 132 | "use-isnan": 2, 133 | "valid-typeof": 2, 134 | "wrap-iife": [2, "any"], 135 | "yoda": [2, "never"], 136 | 137 | "standard/object-curly-even-spacing": [2, "either"], 138 | "standard/array-bracket-even-spacing": [2, "either"], 139 | "standard/computed-property-even-spacing": [2, "even"], 140 | 141 | "react/display-name": 1, 142 | "react/forbid-prop-types": 1, 143 | "react/jsx-boolean-value": 1, 144 | "react/jsx-closing-bracket-location": 0, 145 | "react/jsx-curly-spacing": 1, 146 | "react/jsx-indent-props": 1, 147 | "react/jsx-max-props-per-line": 0, 148 | "react/jsx-no-bind": 1, 149 | "react/jsx-no-duplicate-props": 1, 150 | "react/jsx-no-literals": 1, 151 | "react/jsx-no-undef": 1, 152 | "react/jsx-quotes": 1, 153 | "react/jsx-sort-prop-types": 0, 154 | "react/jsx-sort-props": 0, 155 | "react/jsx-uses-react": 1, 156 | "react/jsx-uses-vars": 1, 157 | "react/no-danger": 1, 158 | "react/no-did-mount-set-state": 1, 159 | "react/no-did-update-set-state": 1, 160 | "react/no-direct-mutation-state": 1, 161 | "react/no-multi-comp": 1, 162 | "react/no-set-state": 0, 163 | "react/no-unknown-property": 1, 164 | "react/prefer-es6-class": 1, 165 | "react/prop-types": 1, 166 | "react/react-in-jsx-scope": 1, 167 | "react/require-extension": 1, 168 | "react/self-closing-comp": 1, 169 | "react/sort-comp": 1, 170 | "react/wrap-multilines": 1 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # Distribution 30 | dist 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-baby-steps 2 | [ ](https://codeship.com/projects/120531) 3 | 4 | Introducing beginners to the world of React via coding. 5 | The goal of this repo is to understand the basic concepts before you start using magic ~Flux libraries. 6 | 7 | If you are looking for the ideas behind React, like VirtualDOM, you should start here: 8 | https://blog.risingstack.com/the-react-way-getting-started-tutorial/ 9 | 10 | Chapters as releases: 11 | https://github.com/RisingStack/react-baby-steps/releases 12 | 13 | ## chapters 14 | 15 | I recommend you to checkout each chapters step by step and see what's changed. 16 | If you are hungry for detailed explanation, ping me on Twitter: https://twitter.com/slashdotpeter 17 | 18 | 1. [Build system](https://github.com/RisingStack/react-baby-steps/releases/tag/01_Build_system) 19 | 2. [Components](https://github.com/RisingStack/react-baby-steps/releases/tag/02_Components) 20 | 3. [Component lifecycle](https://github.com/RisingStack/react-baby-steps/releases/tag/03_Component_Lifecycle) 21 | 4. [Immutable.js](https://github.com/RisingStack/react-baby-steps/releases/tag/04_ImmutableJS) 22 | 5. [Component's state](https://github.com/RisingStack/react-baby-steps/releases/tag/05_Component_state) 23 | 6. [Mixins and LinkState](https://github.com/RisingStack/react-baby-steps/releases/tag/06_Mixins_LinkState) 24 | 7. [Higher order components](https://github.com/RisingStack/react-baby-steps/releases/tag/07_Higher_order_components) 25 | 8. [Context](https://github.com/RisingStack/react-baby-steps/releases/tag/08_Context) 26 | 9. [Component testing](https://github.com/RisingStack/react-baby-steps/releases/tag/09_Component_testing) 27 | 10. [Flux basics with Rx](https://github.com/RisingStack/react-baby-steps/releases/tag/10_Flux_basics_with_Rx) 28 | 11. [Redux](https://github.com/RisingStack/react-baby-steps/releases/tag/11_Redux) 29 | 30 | ## next 31 | 32 | In the future I plan to add more chapters like data fetching, routing and complex data handling with Redux. 33 | 34 | ## run 35 | ``` 36 | npm i 37 | npm run dev 38 | ``` 39 | 40 | ## test 41 | ``` 42 | npm test 43 | ``` 44 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-split", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "mocha --compilers js:babel-register 'src/**/*.spec.js'", 7 | "dev": "webpack-dev-server --port 8081 --config webpack.config.js" 8 | }, 9 | "author": "Peter Marton", 10 | "license": "ISC", 11 | "engines": { 12 | "node": "4.2.3" 13 | }, 14 | "devDependencies": { 15 | "babel-core": "^6.2.1", 16 | "babel-loader": "^6.2.0", 17 | "babel-preset-es2015": "^6.1.18", 18 | "babel-preset-react": "^6.1.18", 19 | "babel-register": "^6.3.13", 20 | "chai": "^3.4.1", 21 | "classnames": "^2.2.1", 22 | "enzyme": "^1.0.0", 23 | "eslint": "^1.10.2", 24 | "eslint-plugin-react": "^3.10.0", 25 | "eslint-plugin-standard": "^1.3.1", 26 | "immutable": "^3.7.5", 27 | "lodash": "^3.10.1", 28 | "mocha": "^2.3.4", 29 | "react": "^0.14.3", 30 | "react-addons-linked-state-mixin": "^0.14.3", 31 | "react-addons-test-utils": "^0.14.3", 32 | "react-dom": "^0.14.3", 33 | "react-immutable-proptypes": "^1.5.0", 34 | "react-mixin": "^3.0.3", 35 | "react-redux": "^4.0.0", 36 | "redux": "^3.0.4", 37 | "sinon": "^1.17.2", 38 | "sinon-chai": "^2.8.0", 39 | "webpack": "^1.12.9", 40 | "webpack-dev-server": "^1.14.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/actions/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import * as items from './itemsActions' 4 | 5 | export default { 6 | items 7 | } 8 | -------------------------------------------------------------------------------- /src/actions/itemsActions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | export const ITEM_TOGGLE_RESOLVED = 'ITEM_TOGGLE_RESOLVED' 4 | 5 | export function itemToggleResolved (id) { 6 | return { 7 | type: ITEM_TOGGLE_RESOLVED, 8 | id 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import React from 'react' 4 | import { render } from 'react-dom' 5 | 6 | import { Provider } from 'react-redux' 7 | import configureStore from './store/configureStore' 8 | 9 | import TodoList from './containers/todoList' 10 | 11 | const store = configureStore() 12 | 13 | render( 14 |