{"id":21497763,"url":"https://github.com/huyle93/react-bible-huyle","last_synced_at":"2026-04-07T09:31:52.615Z","repository":{"id":121947034,"uuid":"132396031","full_name":"huyle93/react-bible-huyle","owner":"huyle93","description":"My everything React stack bible is here. Including the react personal configured boilerplate built on top of create-react-app. This also includes some latest and useful ES2016 syntax of JavaScript.","archived":false,"fork":false,"pushed_at":"2018-05-07T02:45:14.000Z","size":124,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-22T22:37:02.899Z","etag":null,"topics":["es6","javascript","react","reactjs","redux","webpack"],"latest_commit_sha":null,"homepage":"https://huyletech.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/huyle93.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-07T02:23:54.000Z","updated_at":"2023-03-04T05:47:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"93271602-040d-4c4c-b029-528f37e7cfd2","html_url":"https://github.com/huyle93/react-bible-huyle","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/huyle93/react-bible-huyle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huyle93%2Freact-bible-huyle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huyle93%2Freact-bible-huyle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huyle93%2Freact-bible-huyle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huyle93%2Freact-bible-huyle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/huyle93","download_url":"https://codeload.github.com/huyle93/react-bible-huyle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huyle93%2Freact-bible-huyle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31507995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["es6","javascript","react","reactjs","redux","webpack"],"created_at":"2024-11-23T16:26:25.956Z","updated_at":"2026-04-07T09:31:52.592Z","avatar_url":"https://github.com/huyle93.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e This is designed to be an all-encompassing guide to essential principles of ReactJS\n\n![ReactJS](https://cdn-images-1.medium.com/max/1200/1*i3hzpSEiEEMTuWIYviYweQ.png)\n \nStar this repo for the entirety of your ReactJS career: [GitHub Repository](https://github.com/huyle93/react-bible-huyle.git). \n\nWant to make this guide better? View the [issues](https://github.com/huyle93/react-bible-huyle.git/issues), [Pull requests](https://github.com/huyle93/react-bible-huyle.git/pulls) are welcomed!\n\n***\n\n### Facebook Documentation\n\nOriginal Documentation from Facebook\n\n- [Hello World Documentation - Original](https://reactjs.org/docs/hello-world.html)\n- [Basic Tutorials - Original](https://reactjs.org/tutorial/tutorial.html)\n\n\n### ReactJS Intro\n\nIn this guide, you will learn:\n\n- Fundamental ReactJS concepts\n- How to build ES2015 components\n- The component lifecycle\n- Difference between state vs. props\n- Building a client-side React app\n- Build an isomorphic React app\n\nI recommend you break this read into bite-sized sections to better digest the content. Now let's get into it.\n\n## What is ReactJS?\n\nSimply put, it is a JavaScript library for building User Interfaces **(UI)** created and maintained by Facebook.\n\nReactJS makes no assumptions about your technology stack, so you can use ReactJS to: \n\n- Build a widget\n- Add a reusable component (header, footer, etc.)\n- Build the entire front-end experience (like Facebook)\n\nJust to reiterate, you can incorporate ReactJS into different types of front-end tech stacks (AngularJS, Backbone, etc.) or you can choose to build entire applications out of ReactJS!\n\n## The Virtual DOM\n\nYou are going to hear this term all the time. Simply put, ReactJS builds an abstract version of the DOM. ReactJS observes when the data changes, then it will find the difference and re-render what needs to be changed. What makes it fast is:\n\n- Efficient diff algorithms\n- Efficient update of sub-tree only\n\nInstead of traditional HTML:\n\n```html\n...\n\n\u003cdiv\u003e\n\t\u003ch1\u003eThis is a header\u003c/h1\u003e\n\u003c/div\u003e\n...\n\n```\n\nYou will see Component-based programming:\n\n```js\n// Import essentials\nimport React, { Component } from 'react'\nimport { render } from 'react-dom'\n\n// A basic React Component\nclass Header extends Component {\n\trender() {\n\t\treturn (\n\t\t\t{/* JSX code */}\n\t\t\t\u003cdiv\u003e\n\t\t\t\t\u003ch1\u003eThis is a reusable header\u003c/h1\u003e\n\t\t\t\u003c/div\u003e\n\t\t)\n\t}\n}\n\n// Render the Component onto the page\nrender(\u003cHeader /\u003e, mountNode)\n```\n\nIn the above example, you will notice that it uses an XML-like syntax to simulate the DOM. This is called **JSX**, a preprocessor step that allows an elegant way to write ReactJS component. Just like XML, JSX tags will have tag names, attributes, and children. \n\nUsing the Virtual DOM provides:\n\n- A simpler programming model\n- Better performance\n- Server-side rendering\n- Modular, reusable components\n\nFor more information, check out [Virtual Dom](https://github.com/Matt-Esch/virtual-dom).\n\n## Unidirectional Data Flow\n\nReactJS implements a one-way data flow. This means that data is passed from the top-down, through **props**. Data is transferred from the top component to its children, so on and so forth. \n\n```js\n...\n// A simple component flowing down the props\n\u003cComponent {...this.props} some=\"values\" /\u003e\n...\n```\n\nMost times, the properties will be explicitly passed down. \n\n```js\nimport React, { Component } from 'react'\nimport { render } from 'react-dom'\n\nclass FancyForm extends Component {\n\t// When component is initialized\n\tconstructor(props) {\n\t\t// Bring in the props. We can now reference `this.props`\n\t\tsuper(props)\n\t}\n\trender() {\n\t\t// Use spread operators to break apart the props\n\t\tconst { hidden, ...others } = this.props\n\t\t// Determine whether to hide to show div\n\t\tlet formClass = hidden ? 'FormHidden' : 'FormShow'\n\t\treturn (\n\t\t\t{/* Put in the class, pass all the other props down\n\t\t\t\u003cdiv className={formClass} {...others} /\u003e\n\t\t\t...\n\t\t)\n\t}\n}\n\n```\n\nWe will see this in action in the future examples.\n\n## Getting started\n\nGetting started is ReactJS is easy. I have provided a boilerplate [here](https://github.com/stanleycyang/react-bible-boilerplate). \n\nThis [repository](https://github.com/stanleycyang/react-bible-boilerplate) contains:\n\n- The boilerplate \n- The walkthrough \n- All the completed examples \n\nI recommend you **star**, **fork**, or **clone** this repo for your own reference. If you want to follow along, you will need to follow the instructions below:\n\n**Installation:**\n\n```bash\n$ git clone https://github.com/stanleycyang/react-bible-boilerplate.git book-inventory\n$ cd book-inventory\n$ npm install\n```\n\nThe boilerplate includes:\n\n- Babel\n- Webpack\n- Express\n- ReactJS\n\nOnce you have the boilerplate installed, we can get started building some ReactJS components!\n\nOur **roadmap**:\n\n- Client-side ReactJS\n- Isomorphic ReactJS\n\n## Book Inventory (client-side React)\n\nThis is our current directory structure:\n\n\t├── LICENSE\n\t├── README.md\n\t├── bin\n\t│   └── www\n\t├── client\n\t│   ├── container\n\t│   │   └── index.js\n\t│   ├── index.js\n\t│   ├── polyfills.js\n\t│   └── views\n\t│       ├── index.jade\n\t│       └── layout.jade\n\t├── config\n\t│   └── index.js\n\t├── nodemon.json\n\t├── package.json\n\t├── server\n\t│   ├── index.js\n\t│   └── routes\n\t│       └── index.js\n\t└── webpack\n\t    ├── dev.config.js\n\t    ├── index.js\n\t    └── prod.config.js\n\n- **client**: contains all client-side code\n- **server**: contains all server-side code\n- **webpack**: our production and development configurations live here\n- **config**: we place all [ENV](http://www.computerhope.com/jargon/e/envivari.htm) variables here\n- **bin**: We place any scripts (`www`, `seed`, etc.) in here\n\n### Starting the Express Server\n\nTo start the **Express** server, run in the root of the app directory:\n\n```bash\n$ npm run dev\n$ open http://localhost:3000\n```\n\nThis will start a web server at `http://localhost:3000` with **hot reloading** and **nodemon**. This means you can see all the changes in real-time when the files are saved!\n\n### Writing Your First React Component\n\nLet's take a look inside of `client/container/index.js`. Here we will find a very basic React component:\n\n```js\n// client/container/index.js\n\n// Load in React\nimport React, { Component, PropTypes } from 'react'\n\n// Create a basic component called App and export the App to use\nexport default class App extends Component {\n  render() {\n    return (\n      \u003cdiv\u003eHello world! Love, Stanley\u003c/div\u003e\n    )\n  }\n}\n```\n\n**Import \u0026 Export**\n\nIn ReactJS, it is best practice to build apps in a modular fashion. That means you should split up components into different files to better organize it. \n\nYou will see `import` and `export` all throughout our examples. This helps us break up code into different pages.\n\nYou can see the **destructuring assignment syntax** here:\n\n```js\nimport React, { Component, PropTypes } from 'react'\n```\nThis lets us extract multiple object properties in a single line. Now we no longer have to prefix them with React (ie. React.PropTypes or React.Component).\n\nFor more info, here are the MDN docs:\n\n- [Import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n\n**Classes**\n\nIn **ES2015+**, you can build React Components incredibly easy with [`classes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). \n\nJavaScripts classes are syntactical sugar over the prototypical inheritance. It allows us to build templates for objects as such:\n\n```js\nclass Square {\n\t// Constructor gets called when an object is intialized\n\tconstructor(height, width) {\n\t\tthis.height = height;\n\t\tthis.width = width;\n\t}\n}\n\n// Initialize a new Square\nlet Shape = new Square(10, 10)\n```\n\nIn React, we use the **extends** keyword to create a class as a child to the React Component. \n\n```js\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003eHello world! Love, Stanley\u003c/div\u003e\n    )\n  }\n}\n```\n\nIf you're not familiar with Object-oriented programming with JavaScript, I recommend taking a look at [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript).\n\nNotice how we have a **render()** method? For every React component, the render method is **absolutely required**. \n\nYou can **return null or false** to indicate that you don't want to render anything. Behind the scenes, React renders a `\u003cnoscript\u003e` tag to work with the React diffing algorithm.\n\nThe **render()** function should be pure. It should NOT modify the component state, and it does not read from or write to the DOM. If you want to interact with the browser, you should perform the work in **componentDidMount()** or another component lifecycle method. \n\n## Component Lifecycle\n\nReact Components have built-in methods to handle component lifecycle events. The lifecycle starts from before the component gets mounted onto the page to when the component is dismounted from the page. \n\n### [Lifecycle methods](https://facebook.github.io/react/docs/component-specs.html):\n\nI will reference the descriptions from the [ReactJS documentation](https://facebook.github.io/react/docs/component-specs.html) in this section. If you are familiar with the component lifecycle methods already, feel free to skip this section.\n\n### Mount methods:\n\n**componentWillMount:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentWillMount() {\n\t\t// Run code before component is initially rendered\n\t}\n\t...\n}\n```\n\nThis method is invoked once, both on the client and server, immediately before the initial rendering occurs. \n\nIf you call setState within this method, render() will see the updated state and will be executed only once despite the state change.\n\n**componentDidMount:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentDidMount() {\n\t\t// Run code after component is initially rendered\n\t}\n\t...\n}\n```\n\nThis method is invoked once, only on the client (not on the server), immediately after the initial rendering occurs. \n\nAt this point in the lifecycle, you can access any refs to your children (e.g., to access the underlying DOM representation). \n\nThe componentDidMount() method of child components is invoked before that of parent components.\n\n### Update methods:\n\n**componentWillReceiveProps:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentWillReceiveProps(nextProps) {\n\t\t// Invoked when component is receiving new props\n\t}\n\t...\n}\n```\n\nThis method is invoked when a component is receiving new props. This method is not called for the initial render.\n\nUse this as an opportunity to react to a prop transition before render() is called by updating the state using this.setState(). The old props can be accessed via this.props. \n\nCalling this.setState() within this function will not trigger an additional render\n\n**shouldComponentUpdate:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tshouldComponentUpdate(nextProps, nextState) {\n\t\t// Invoked before rendering as new props\tor state are being received. \n\t}\n\t...\n}\n```\n\nThis method is invoked before rendering when new props or state are being received. \n\nThis method is not called for the initial render or when forceUpdate is used.\n\nUse this as an opportunity to return false when you're certain that the transition to the new props and state will not require a component update.\n\n**componentWillUpdate:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentWillUpdate(nextProps, nextState) {\n\t\t// Invoked immediately before rendering as new props\tor state are being received. \n\t}\n\t...\n}\n```\n\nThis method is invoked immediately before rendering when new props or state are being received. This method is not called for the initial render.\n\nUse this as an opportunity to perform preparation before an update occurs.\n\nYou cannot use this.setState() in this method. If you need to update state in response to a prop change, use componentWillReceiveProps instead.\n\n**componentDidUpdate:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentDidUpdate(prevProps, prevState) {\n\t// Invoked immediately after updates are flushed to the DOM\n\t}\n\t...\n}\n```\n\nThis method is invoked immediately after the component's updates are flushed to the DOM. This method is not called for the initial render.\n\nUse this as an opportunity to operate on the DOM when the component has been updated.\t\n\n### Unmount method:\n\n**componentWillUnmount:**\n\nUsage:\n\n```js\n...\nclass ExampleComponent extends Component {\n\t...\n\tcomponentWillUnmount() {\n\t\t// Run code before component is dismounted from DOM\n\t}\n\t...\n}\n```\n\nThis method is invoked immediately before a component is unmounted from the DOM.\n\nPerform any necessary cleanup in this method, such as invalidating timers or cleaning up any DOM elements that were created in componentDidMount.\n\nWith this understanding of the component lifecycle, we can now build out our React client-side app.\n\n## Building the Front-end\n\nThis is the app that we will be creating today:\n\n![What our app will look like](https://s3-us-west-1.amazonaws.com/stanleycyang-v2/Screen Shot 2016-01-18 at 7.00.53 PM.png-d5288f410fc69df79ad16eee8b7379524a22947d)\n\nOur webpack is connected to our client-side code via `client/index.js`. I have already connected and rendered our app for you today:\n\n```js\n// Imports React\nimport React from 'react'\n// Imports the render method from react-dom\nimport { render } from 'react-dom'\n\n// Brings in our App\nimport App from './container'\n\n// Renders the app onto the node #root\nrender(\u003cApp /\u003e, document.querySelector('#root'))\n```\n\nI want to stop and point out the **render method** from the **react-dom** package. This is important.\n\nThe render method takes two arguments: reactElement and domContainerNode\n\n```js\nReactDOM.render(reactElement, domContainerNode)\n```\n\nThis method helps us actually render the React Components onto the browser. If you take it out, your components will no longer show up on the page. Try it!\n\n## Breaking down the Components\n\n![App Breakdown](https://s3-us-west-1.amazonaws.com/stanleycyang-v2/Screen Shot 2016-01-18 at 7.00.53 PM.png-11b27f714dd57323c2903efef2f629cb1bc7dac1)\n\nTaking a look at this app, it's simple for us to break it down into 5 components:\n\n- BookInventory (The container for our app)\n- BookBox (Wraps BookForm and BookList)\n- BookForm (Contains the form to post new books)\n- BookList (Shows the list of books. Wraps Book)\n- Book (The book itself)\n\nWe're going to create a `components` folder inside `client`, then create 4 files:\n\n```bash\n$ cd client\n$ mkdir components\n$ cd components\n$ touch BookBox.js BookForm.js BookList.js Book.js\n```\n\n## Building the BookInventory container\n\nWe want to seed some static data into our example. Inside of your container, let's seed an array of books to use. We will adjust our `client/container/index.js` to look like this:\n\n```js\n'use strict'\n\n// Import React\nimport React, { Component, PropTypes } from 'react'\n\n// Import components\nimport BookBox from '../components/BookBox'\n\n/* polyfills. This allows us to use advanced JS features without being held back by older browsers or versions */\nimport '../polyfills'\n\n// Seeded book data\nlet books = [\n  {\n    title: 'Harry Potter and the Philosopher\\'s Stone',\n    author: 'J. K. Rowling',\n    isbn: '0747532699'\n  },\n  {\n    title: 'Harry Potter and the Chamber of Secrets',\n    author: 'J. K. Rowling',\n    isbn: '0439064864'\n  },\n  {\n    title: 'Harry Potter and the Prisoner of Azkaban',\n    author: 'J. K. Rowling',\n    isbn: '0439136350'\n  },\n  {\n    title: 'Harry Potter and the Goblet of Fire',\n    author: 'J. K. Rowling',\n    isbn: '0439139600'\n  },\n  {\n    title: 'Harry Potter and the Order of the Phoenix',\n    author: 'J. K. Rowling',\n    isbn: '0439358078'\n  },\n  {\n    title: 'Harry Potter and the Half-Blood Prince',\n    author: 'J. K. Rowling',\n    isbn: '0439785960'\n  },\n  {\n    title: 'Harry Potter and the Deathly Hallows',\n    author: 'J. K. Rowling',\n    isbn: '0545139708'\n  }\n]\n\n// Change the name to BookInventory\nexport default class BookInventory extends Component {\n  render() {\n  \t{/* We want to pass down the seeded book data into our BookBox as props */}\n    return (\n      \u003cmain\u003e\n        \u003cBookBox initialBooks={ books } /\u003e\n      \u003c/main\u003e\n    )\n  }\n}\n```\n\nIf you look inside the **render** method, you will see that we return the BookBox component with initialBooks:\n\n```js\n...\nreturn (\n  \u003cmain\u003e\n    \u003cBookBox initialBooks={ books } /\u003e\n  \u003c/main\u003e\n)\n...\n```\nWhat it means is that we created a **prop** called initialBooks and we assigned the **books** data to it. \n\nTherefore, you can imagine it as the **BookInventory** component passing the books data to its child, **BookBox**.\n\nAt this point, you will see an error. However, don't worry too much about it since we haven't created the BookBox component yet.\n\n### What are [props](https://facebook.github.io/react/docs/transferring-props.html)?\n\nShort for **properties**, they are a component's configuration. They flow from the top down and are immutable in the components which receive them. \n\nA component cannot change its props, but it is responsible for putting together the props of its children components.\n\nWhen certain data is necessary throughout different parts of an app, its best to pass them down as props. \n\n## BookBox\n\nBookBox is going to hold our other two components, BookList and BookForm. Inside `client/components/BookBox.js`, let's put the following:\n\n```js\n'use strict'\n\nimport React, { Component, PropTypes } from 'react'\n\n// Import React Components\nimport BookList from './BookList'\nimport BookForm from './BookForm'\n\nexport default class BookBox extends Component {\n  // Seed a list of default props (Harry Potter series)\n  static defaultProps = {\n    initialBooks: [\n      {\n        title: 'Twilight',\n        author: 'Stephanie Meyer',\n        isbn: '0316015849'\n      }\n    ]\n  };\n\n  // Verifies that the array of books exist\n  static propTypes = {\n    initialBooks: PropTypes.array.isRequired\n  };\n\n  // When the component is initialized\n  constructor(props) {\n  \t // Passes down the props to this component\n    super(props)\n\n    // Set the initialBooks prop into the state 'books'\n    this.state = {\n      books: this.props.initialBooks\n    }\n  }\n\n\n  render() {\n    const { books } = this.state\n    return (\n      \u003cdiv className=\"ui container\"\u003e\n        \u003ch1 className=\"title ui center aligned dividing header\"\u003eBook Inventory\u003c/h1\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nPlease note that JSX attributes are **camel-cased**. For example, class is className instead. For a detailed list of HTML attributes, you can see them [here](https://facebook.github.io/react/docs/tags-and-attributes.html).\n\nThe great part about React components is that you can use **defaultProps** to set the properties if none have been provided, and you can also use **propTypes** to make sure that the properties exists. \n\n```js\nstatic defaultProps = {\n\tinitialBooks: [\n\t  {\n\t    title: 'Twilight',\n\t    author: 'Stephanie Meyer',\n\t    isbn: '0316015849'\n\t  }\n\t]\n};\n```\nIf the prop initialBooks wasn't provided, it would have defaulted to Twilight by Stephanie Meyer.\n\nThe static keyword used denotes that this is a [**class property**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static).\n\n```js\nstatic propTypes = {\n    initialBooks: PropTypes.array.isRequired\n};\n```\n\npropTypes will check if the initialBooks property is passed down, and that it is an array. If the checks don't pass, an error will be thrown inside your console. \n\nFor more information, read [here](https://facebook.github.io/react/docs/reusable-components.html). \n\nIn the constructor method, you will also notice that we are setting the state of the component:\n\n```js\nconstructor(props) {\n\t // Passes down the props to this component\n\tsuper(props)\n\t\n\t// Set the initialBooks prop into the state 'books'\n\tthis.state = {\n\t  books: this.props.initialBooks\n\t}\n}\n```\n\nThe default value of state should always be set inside the constructor. In this case, we fed the initialBooks prop into the state of the BookBox component. \n\nUsually, you don't want to pass the prop into the state because it create 2 or more sources of truths in your app. \n\nHowever in this instance, we have stated clearly that we will only be using the initialBooks as the starting state for the component.\n\n### What is state?\n\nA state is component-specific, and starts with a default value set inside of the **constructor** method.\n\nIt can be mutated in time (usually due to user events). It's a representation of the component at one point in time - a snapshot. \n\nA component manages its own state internally, and it has no business changing the state of its children (except on the initial state). \n\n## Book\n\nWe want to create a list of books. The **Book** component should represent the individual books in the list.\n\nIn your `client/components/Book.js`:\n\n```js\n'use strict'\n\nimport React, { Component, PropTypes } from 'react'\n\nexport default class Book extends Component {\n  // Validate the props flowing in\n  static propTypes = {\n    author: PropTypes.string.isRequired,\n    title: PropTypes.string.isRequired\n  };\n\n  render() {\n    const { author, title } = this.props\n    return (\n      \u003cdiv className=\"book\"\u003e\n        \u003ch2 className=\"title\"\u003e\n          { title }\n        \u003c/h2\u003e\n        \u003cp className=\"author\"\u003e{ author }\u003c/p\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nIn the Book component, we will validate that the author and title (string) are passed down into it. \n\nAfter receiving the props, the component will simply show them inside a `\u003ch2\u003e` and `\u003cp\u003e` tag.\n\nNow onto the list itself.\n\n## BookList\n\nThe BookList should render the array of books. We will need to make use of the JS [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function to achieve this.\n\nIn your `client/components/BookList.js`:\n\n```js\n'use strict'\n\nimport React, { Component, PropTypes } from 'react'\nimport Book from './Book'\n\nexport default class BookList extends Component {\n  static propTypes = {\n    books: PropTypes.array.isRequired,\n    removeBook: PropTypes.func.isRequired\n  };\n\n  render() {\n    const { removeBook } = this.props\n\n    // Create a new array with map and store it within bookNodes\n    let bookNodes = this.props.books.map((book, i) =\u003e {\n      return (\n        \u003cdiv key={ book.isbn } className=\"ui segment\"\u003e\n          \u003cBook author={ book.author } title={ book.title } /\u003e\n          \u003cbr /\u003e\n          \u003cbutton className=\"ui red right labeled icon button\" onClick={ removeBook.bind(null, i) }\u003e\n            \u003ci className=\"trash icon\"\u003e\u003c/i\u003e\n            Delete\n          \u003c/button\u003e\n        \u003c/div\u003e\n      )\n    })\n\n    return (\n      \u003cdiv className=\"bookList\"\u003e\n      \t {/* render the book list */}\n        { bookNodes }\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nThe complexity in this component is the **removeBook** method. Since books are passed down from the **BookBox** component, we will need to write the removeBook method inside of BookBox component to modify the state (remember, props need to be modified from the source). Then flow the function **removeBook** into the **BookList component**.\n\nInside of the `client/components/BookBox.js`, add the **removeBook** method and insert the BookList component into the render method:\n\n```js\n...\nexport default class BookBox extends Component {\n\t...\n  constructor(props) {\n    super(props)\n\n    // Set the initialBooks prop into the state 'books'\n    this.state = {\n      books: this.props.initialBooks\n    }\n  }\n\n  // Remove book\n  removeBook = (index) =\u003e {\n    let books = this.state.books\n    books.splice(index, 1)\n    this.setState({\n      books\n    })\n  };\n\n  render() {\n    const { books } = this.state\n    return (\n      \u003cdiv className=\"ui container\"\u003e\n        \u003ch1 className=\"title ui center aligned dividing header\"\u003eBook Inventory\u003c/h1\u003e\n        \u003cdiv className=\"ui items\"\u003e\n          \u003cBookList books={ books } removeBook={ this.removeBook } /\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nAt this point in time, you should see the list rendered on your page! You should also be able to use the deletion feature to remove any of the seeded books. \n\nThe last part of our client app: The book posting feature.\n\n## BookForm\n\nWe need to create a form to allow users to post new books. \n\nIn your `client/components/BookForm.js`, put the following:\n\n```js\nimport React, { Component, PropTypes } from 'react'\nimport { findDOMNode } from 'react-dom'\n\nexport default class BookForm extends Component {\n\n  constructor(props) {\n    super(props)\n\n    // Set the state of the BookForm Component\n    this.state = {\n      isbn: '',\n      author: '',\n      title: ''\n    };\n  }\n\n  componentDidMount() {\n    // Focus on the isbn input\n    findDOMNode(this.refs.isbn).focus()\n  }\n\n  // Method for handling state of ISBN\n  handleISBNChange = (e) =\u003e {\n    // Set the new ISBN\n    this.setState({\n      isbn: e.target.value.trim()\n    })\n  };\n\n  // Method for handling state for Author\n  handleAuthorChange = (e) =\u003e {\n    // Sets the new author\n    this.setState({\n      author: e.target.value.trim()\n    })\n  };\n\n  // Method for handling state for Title\n  handleTitleChange = (e) =\u003e {\n    // Sets the new title\n    this.setState({\n      title: e.target.value.trim()\n    })\n  };\n\n  handleSubmit = (e) =\u003e {\n    const { addBook } = this.props\n    const { isbn, author, title } = this.state\n    e.preventDefault()\n\n    if (!isbn || !author || !title) return\n\n    addBook({\n      isbn,\n      author,\n      title\n    })\n\n    this.setState({\n      isbn: '',\n      author: '',\n      title: ''\n    })\n\n  };\n\n  render() {\n    return (\n      \u003cform className=\"bookForm ui form\" onSubmit={ this.handleSubmit }\u003e\n\n        \u003cdiv className=\"three fields\"\u003e\n          {/* ISBN */}\n          \u003cdiv className=\"field\"\u003e\n            \u003clabel\u003eISBN\u003c/label\u003e\n            \u003cinput type=\"text\" placeholder=\"ISBN\" onChange={ this.handleISBNChange } ref=\"isbn\" value={ this.state.isbn } /\u003e\n          \u003c/div\u003e\n\n          {/* Author name */}\n          \u003cdiv className=\"field\"\u003e\n            \u003clabel\u003eAuthor\u003c/label\u003e\n            \u003cinput type=\"text\" placeholder=\"Author name\" onChange={ this.handleAuthorChange } value={ this.state.author } /\u003e\n          \u003c/div\u003e\n\n          {/* Book title */}\n          \u003cdiv className=\"field\"\u003e\n            \u003clabel\u003eTitle\u003c/label\u003e\n            \u003cinput type=\"text\" placeholder=\"Book title\" onChange={ this.handleTitleChange } value={ this.state.title } /\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n\n        {/* Submit button */}\n        \u003cbutton className=\"fluid ui button green right labeled icon\" type=\"submit\"\u003e\n          \u003ci className=\"right arrow circle outline icon\"\u003e\u003c/i\u003e\n          Add new book\n        \u003c/button\u003e\n\n      \u003c/form\u003e\n    )\n  }\n}\n```\n\nIn this example, you are going to use the component's state to manage the different inputs. Therefore, you have to set the initial state:\n\n```js\n...\n  constructor(props) {\n    super(props)\n\n    // Set the state of the BookForm Component\n    this.state = {\n      isbn: '',\n      author: '',\n      title: ''\n    };\n  }\n...\n```\n\nYou want to focus on the **ISBN** input when the page is loaded.\n\n```js\n...\n  componentDidMount() {\n    // Focus on the isbn input\n    findDOMNode(this.refs.isbn).focus()\n  }\n...\n{/* ISBN */}\n  \u003cdiv className=\"field\"\u003e\n    \u003clabel\u003eISBN\u003c/label\u003e\n    \u003cinput type=\"text\" placeholder=\"ISBN\" onChange={ this.handleISBNChange } ref=\"isbn\" value={ this.state.isbn } /\u003e\n  \u003c/div\u003e\n...\n```\n\n[Ref](https://facebook.github.io/react/docs/more-about-refs.html) allows you find DOM markup rendered by a component. In this case, ref was used to grab the ISBN input to focus on it on component mount with the help of [findDOMNode](https://facebook.github.io/react/docs/top-level-api.html).\n\n### POSTing the form\n\nTo post the form, we will create 4 different methods: \n\n- handleISBNChange\n- handleAuthorChange\n- handleTitleChange\n- handleSubmit\n\nEssentially, they will mutate the state when the user types into them.\n\n```js\n  handleTitleChange = (e) =\u003e {\n    // Sets the new title\n    this.setState({\n      title: e.target.value.trim()\n    })\n  };\n```\n\nThe **setState** method is what we can use to mutate the state. When the user finally finishes typing the input, the state of **BookForm** will contain the book object to be posted.\n\nFinally, we want to add a handleSubmit method to the form to handle the POST.\n\n```js\n  handleSubmit = (e) =\u003e {\n    const { addBook } = this.props\n    const { isbn, author, title } = this.state\n    e.preventDefault()\n\n    if (!isbn || !author || !title) return\n\n    addBook({\n      isbn,\n      author,\n      title\n    })\n\n    this.setState({\n      isbn: '',\n      author: '',\n      title: ''\n    })\n\n  };\n```\n\nNotice how we need an **addBook** prop to be flowed down? Let's go back and create the **addBook** method in **BookBox**.\n\nIn `client/components/BookBox`, modify it to look like this:\n\n```js\n...\n\nexport default class BookBox extends Component {\n  ...\n\n  constructor(props) {\n    super(props)\n\n    // Set the initialBooks prop into the state 'books'\n    this.state = {\n      books: this.props.initialBooks\n    }\n  }\n\n  // Add book\n  addBook = (book) =\u003e {\n    let books = this.state.books\n    books.unshift(book)\n    this.setState({\n      books\n    })\n  };\n\n  ...\n\n  render() {\n    const { books } = this.state\n    return (\n      \u003cdiv className=\"ui container\"\u003e\n        \u003ch1 className=\"title ui center aligned dividing header\"\u003eBook Inventory\u003c/h1\u003e\n        \u003cBookForm addBook={ this.addBook } /\u003e\n        \u003cdiv className=\"ui items\"\u003e\n          \u003cBookList books={ books } removeBook={ this.removeBook } /\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nThe **addBook** method will put the new book object into the front of the array, and then change the state to include the newest book.\n\nAt this point, you should be able to post new books into the Book Inventory!\n\nIf your goal is to learn how to create purely client-side React apps, you can conclude the tutorial here. \n\nHowever, if you want to learn how to make isomorphic React apps, continue onto the next section!\n\n## Isomorphic Book Inventory App\n\n\ti-so-mor-phic: corresponding or similar in form and relations.\n\n**Isomorphic JavaScript** means that JavaScript is rendered on the server AND the client!\n\nIt is pretty amazing. Don't believe me? Check out this [AirBnb blog](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/) on Isomorphic JavaScript.\n\nThe primary benefits of doing isomorphic JavaScript are:\n\n- Better UX\n- Search engine indexability\n- Easier code maintainence\n\nSince the components will be initially loaded from the server-side, they won't have that initial awkward loading state that you will see in most modern apps. This allows them to be easily indexable while making the UX better.\n\nLet's make a copy of the client-side Book Inventory app and call it isomorphic-book-inventory:\n\n\n```js\n$ cp -r book-inventory isomorphic-book-inventory\n$ cd isomorphic-book-inventory\n```\n\nAll you need to do to make our current app is to make a slight adjustment to our current `server/routes/index.js`:\n\n```js\nimport React, { createFactory } from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { Router } from 'express'\nimport App from '../../client/container'\n\nconst router = Router()\nconst component = createFactory(App)\n\n// For our SPA\nrouter.get('/', (req, res, next) =\u003e {\n  res.render('index', {\n    title: 'Book Inventory',\n    component: renderToString(component({}))\n  })\n})\n\nexport default router\n```\n\nTwo important things we need to focus on here:\n\n- createFactory\n- renderToString\n\n### What is a Factory?\n\nA **ReactElement-factory** is simply a function that generates a ReactElement with a particular type property.\n\nThe source code looks like this:\n\n```js\nfunction createFactory(type) {\n  return React.createElement.bind(null, type);\n}\n```\n\nWhen coupled with **[renderToString](https://facebook.github.io/react/docs/top-level-api.html)**, you can render the ReactElement to its initial HTML. This then send the markup down on the initial request for faster page loads and allow search engines to crawl the pages for SEO purposes.\n\nIf you're getting a hot reloading error, adjust your `.babelrc` to this:\n\n```js\n{\n  \"presets\":  [\"es2015\", \"react\", \"stage-0\"],\n  \"plugins\":  [\"transform-decorators-legacy\", \"transform-class-properties\", \"transform-object-rest-spread\", \"syntax-async-functions\",\"transform-regenerator\", \"transform-runtime\"]\n}\n```\n\nFor handling the fetch error, empty out the `polyfills.js`.\n\n\n## Modifying your Jade file\n\nNow you just need to render the **component** variable into the root (`client/views/index.jade`):\n\n```jade\nextends layout\n\nblock content\n  div#root!=component\n  script(src=\"//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\" defer)\n  script(src=\"/dist/bundle.min.js\" defer)\n```\n\nNow our app is render from the server! Your isomorphic app is complete!\n\nIf you want your app to look like mine, you can install semantic UI into your app and it'll instantly be prettified: [Getting Started - Semantic UI](http://semantic-ui.com/introduction/getting-started.html)\n\n## Flux Architecture\n\nInterested in learning about the **Flux** architecture? I recommend reading the  [**Mastering React Redux**](https://www.stanleycyang.com/tutorials/mastering-react-redux) tutorial to learn the fundamentals of [Redux](https://www.stanleycyang.com/tutorials/mastering-react-redux).\n\n## Conclusions\n\nThrough this guide, you have learned:\n\n- The fundamental concepts of ReactJS\n- Built a client-side React app\n- Built an isomorphic React app\n\nBuilding in ReactJS is awesome. You can choose to use it in parts, or use it for an entire application. With a great community, you can count on ReactJS to continue improving for the long-haul!\n\n## Cite \u0026 Reference\n\nThis repo is developed on top of [react-bible-boilerplate](https://github.com/stanleycyang/react-bible-boilerplate) of stanleycyang github. stanleycyang seems like stopped developing it since 2016.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuyle93%2Freact-bible-huyle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhuyle93%2Freact-bible-huyle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuyle93%2Freact-bible-huyle/lists"}