Nate's Work
- Got my front end with most of my nested routes set up this week.
- Used this blog post as a reference for setting up nested routes: https://tylermcginnis.com/react-router-nested-routes/
- Used this video as a reference for properly setting up react router v4 with create-react-app: https://egghead.io/lessons/react-run-the-react-router-v4-examples-with-create-react-app and this one https://reacttraining.com/react-router/web/guides/quick-start
- Used this article as a reference in better understanding how my app works https://www.fullstackreact.com/articles/deploying-a-react-app-with-a-server/
- Set up my server and front-end to successfully talk to each-other via http fetch requests
Explanation of File Structure and how my App is setup in development and production
- Below is a screenshot of my project directory.  It's essentially a boilerplate rails app without any views.  Instead, a client folder is nested inside with a boilerplate react app generated by create-react-app.  Right now my dependency list is pretty minimal.  Here's the package.json:
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:3001",
  "dependencies": {
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}
- I added react-router-dom for routing purposes.  It's a package that lets me decide which component is being rendered based on the url.
- I also added the line: "proxy": "http://localhost:3001, which tells the react development server to proxy requests to my rails server running on port 3001.  This allows me to make http requests in development without generating cross-origin errors.  This will be removed in production.
- In development I've set up a rake task using foreman that starts my webpack-dev-server at port 3000 and my rails server at port 3001.  They both update as changes are made.
start.rake
namespace :start do
  task :development do
    exec 'foreman start -f Procfile.dev'
  end
procfile.dev
web: cd client && PORT=3000 npm start
api: PORT=3001 && bundle exec rails s
- There's a bit of magic happening behind react-scripts start and react-scripts test.  Here's an example of the dev dependencies in a project I made without create-react-app:
  "devDependencies": {
    "enzyme": "^3.1.0",
    "jasmine-core": "^2.8.0",
    "jasmine-enzyme": "^4.0.1",
    "karma": "^1.7.1",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.1.0",
    "karma-phantomjs-launcher": "^1.0.4",
    "karma-webpack": "^2.0.5",
    "phantomjs-prebuilt": "^2.1.15",
    "react-addons-test-utils": "^15.6.2",
    "react-test-renderer": "^16.0.0",
    "webpack-dev-server": "^2.9.3"
  }
- Lots of packages to set up the testing environment that are entirely encapsulated in "react-scripts: test".  In my case I was using enzyme and jasmine to set up the mocking and testing library, using karma-webpack as the run-time environment and phantomjs as the headless browser.  Create-react-app is set up to use jest which is billed to be all-inclusive.
- I believe "start": "react-scripts start" essentially just boots up the webpack-dev-server.
- Upon deployment "build": "react-scripts build" will get executed and export everything into a static, deployable bundle.  There are two ways I'm considering deploying the app.  
- One is to host my bundled react code as a static site on a service like amazon s3... or the apache server on my linnode, then host my rails back-end in a more responsive environment, either on heroku or with a bit more work, on my linnode.  The user would download the static bundle of JS/CSS/HTML that make up react and that bundle would make requests to my API server.
- The other is to host them together in one environment and set it up so my rails server serves up my bundled JS/CSS/HTML at the root directory "/" and serves up the properly requested data at api/v1/classrooms and associated addresses.  An example of one request can be seen here:
  componentDidMount() {
    fetch(`/api/v1/classrooms`, {
      credentials: 'same-origin',
      method: 'GET',
      headers: { 'Content-Type': 'application/json' }
    })
    .then(response => {
      if (response.ok) {
          return response;
        } else {
          let errorMessage = `${response.status} (${response.statusText})`,
          error = new Error(errorMessage);
          throw(error);
        }
      })
    .then(response => response.json())
    .then(body => {
          this.setState({classroomArray: body.classrooms})
      })
    .catch(error => console.error(`Error in fetch: ${error.message}`));
    }