Skip to content

Commit 685209f

Browse files
committed
add react router and render server
1 parent 182fd52 commit 685209f

File tree

18 files changed

+529
-399
lines changed

18 files changed

+529
-399
lines changed

README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,30 @@
77
3. Start mongodb: `mongod`
88
4. Start dev reactjs: `yarn start` || `npm start`
99
5. Start dev server: `yarn run server` || `npm run server`
10+
6. Build: `yarn run build` || `npm run build`
11+
7. Preview after build: `yarn run prod` || `npm run prod`
1012
## Deployment
1113
- Setup:
1214
1. `heroku create $APP_NAME`
13-
2. `heroku buildpacks:add --index 1`
14-
3. `https://github.com/hunghkit/create-react-app-buildpack.git `
15-
4. `heroku buildpacks:add --index 2 heroku/nodejs`
15+
2. `heroku buildpacks:add --index 1 https://github.com/mars/create-react-app-buildpack.git `
16+
3. `heroku buildpacks:add --index 2 heroku/nodejs`
1617
- Deploy:
1718
`git push heroku yourbanch:master`
19+
## Done
20+
1. Config data with create-react-app
21+
2. Use scss with node-sass
22+
3. Renderserver side
23+
4. Deploy with heroku
24+
5. React router
25+
6. Example with REST
1826
## Todo next
1927
1. `redux` or `mobx`
20-
2. `react-router`
21-
3. `render server`
2228
4. `deploy to aws`
23-
## Noti
29+
## Relation
2430
1. With reactjs see more [create react app](https://github.com/facebookincubator/create-react-app)
2531
2. Proxy with development, you change port or url in proxy in package.json
32+
3. React router dom see more [click here](https://github.com/ReactTraining/react-router)
33+
4. Seo with reactjs see more [click here](https://github.com/nfl/react-helmet)
34+
5. Api with express see more [click here](https://expressjs.com/en/guide/routing.html)
35+
6. Database with mongoosejs see more [click here](http://mongoosejs.com/docs/guide.html)
2636
## Licence: MIT
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3-
import App from './App';
3+
import Home from 'components/Home';
44

55
it('renders without crashing', () => {
66
const div = document.createElement('div');
7-
ReactDOM.render(<App />, div);
7+
ReactDOM.render(<Home />, div);
88
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import Task from 'components/Task';
4+
5+
it('renders without crashing', () => {
6+
const div = document.createElement('div');
7+
ReactDOM.render(<Task />, div);
8+
});

app/components/Home/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from 'react';
22
import logo from 'assets/images/logo.svg';
33
import Task from 'components/Task';
4+
import axios from 'axios';
45

56
class Home extends Component {
67
constructor(props) {
@@ -12,8 +13,8 @@ class Home extends Component {
1213
}
1314

1415
componentWillMount() {
15-
fetch('/api/v1.0.0/connected')
16-
.then((res) => res.json())
16+
axios.get('/api/v1.0.0/connected')
17+
.then((res) => res.data)
1718
.then(({ message }) => this.setState({ message }))
1819
.catch((err) => this.setState({ message: err.toString() }))
1920
}

app/components/Task/Form.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
3+
import axios from 'axios';
34

45
export class Form extends Component {
56
static propTypes = {
@@ -30,24 +31,18 @@ export class Form extends Component {
3031
e.preventDefault();
3132
const { id, title } = this.state;
3233
let url = '/api/v1.0.0/tasks/';
33-
let method = 'POST';
34+
let method = 'post';
3435
let isNew = true;
3536
if (id) {
3637
url += id;
37-
method = 'PUT';
38+
method = 'put';
3839
isNew = false;
3940
}
4041

4142
this.setState({ error: '' });
4243

43-
fetch(url, {
44-
method,
45-
headers: {
46-
'Content-Type': 'application/json'
47-
},
48-
body: JSON.stringify({ task: { title } })
49-
})
50-
.then((res) => res.json())
44+
axios[method](url, { task: { title } })
45+
.then((res) => res.data)
5146
.then(({ task, success, message }) => {
5247
if(success) {
5348
this.setState({ title: '' });

app/components/Task/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { Component } from 'react';
22
import Form from './Form';
3+
import axios from 'axios';
34

45
export class Task extends Component {
56
constructor(props) {
@@ -14,8 +15,8 @@ export class Task extends Component {
1415
}
1516

1617
componentDidMount() {
17-
fetch('/api/v1.0.0/tasks')
18-
.then((res) => res.json())
18+
axios.get('/api/v1.0.0/tasks')
19+
.then((res) => res.data)
1920
.then(({ tasks }) => this.setState({ tasks: tasks.reduce((obj, item) => ({ ...obj, [item._id]: item }), {}) }))
2021
.catch((err) => this.setState({ message: err.toString() }))
2122
}
@@ -31,7 +32,7 @@ export class Task extends Component {
3132

3233
onDelete(e, id) {
3334
e.preventDefault()
34-
if (window.confirm("Are you sure?")) {
35+
if (window.confirm("Are you sure?")) { // eslint-disable-line
3536
const { tasks = {} } = this.state;
3637
delete tasks[id];
3738
this.setState({ tasks: { ...tasks } })
@@ -60,7 +61,7 @@ export class Task extends Component {
6061
<div className="task-component">
6162
<Form ref={(ref) => this.form = ref} onSuccess={this.onSuccess} />
6263
<ul>
63-
{Object.values(tasks).map(this.renderTask)}
64+
{Object.keys(tasks).map((key, index) => this.renderTask(tasks[key], index))}
6465
</ul>
6566
</div>
6667
);

app/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
2-
import ReactDOM from 'react-dom';
3-
import './assets/scss/theme.scss';
4-
import Home from './components/Home';
2+
import { render } from 'react-dom';
3+
import { BrowserRouter } from 'react-router-dom';
4+
import App from 'pages';
55

6-
ReactDOM.render(<Home />, document.getElementById('root'));
6+
render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));

app/pages/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import Helmet from "react-helmet";
3+
import { Switch, Route } from 'react-router-dom';
4+
import 'assets/scss/theme.scss';
5+
6+
import Home from 'components/Home';
7+
8+
const Pages = () => (
9+
<div className="page-container">
10+
<Helmet
11+
htmlAttributes={{lang: "en", amp: undefined}} // amp takes no value
12+
titleTemplate="%s | ReactJS Begin"
13+
titleAttributes={{ itemprop: "name", lang: "en" }}
14+
meta={[
15+
{name: "description", content: "Server side rendering with reactjs begin"},
16+
{name: "viewport", content: "width=device-width, initial-scale=1"},
17+
]}
18+
/>
19+
<Switch router={{}}>
20+
<Route exact path='/' component={Home} />
21+
</Switch>
22+
</div>
23+
);
24+
25+
export default Pages;

app/renderServer/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
import ReactDOMServer from 'react-dom/server';
3+
import { StaticRouter } from 'react-router-dom';
4+
import { Helmet } from "react-helmet";
5+
import Template from './template';
6+
import App from 'pages';
7+
8+
export default (assets) =>
9+
(req, res, next) => {
10+
const context = {};
11+
const markup = ReactDOMServer.renderToString(
12+
<StaticRouter location={req.url} context={context}>
13+
<App />
14+
</StaticRouter>
15+
);
16+
const helmet = Helmet.renderStatic();
17+
18+
res.status(200).send(Template({
19+
markup,
20+
helmet,
21+
assets,
22+
}));
23+
};

app/renderServer/template.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default ({ markup, helmet, assets }) => (`
2+
<!doctype html>
3+
<html ${helmet.htmlAttributes.toString()}>
4+
<head>
5+
${helmet.title.toString()}
6+
${helmet.meta.toString()}
7+
${helmet.link.toString()}
8+
<link href="/${assets['main.css']}" rel="stylesheet">
9+
</head>
10+
<body ${helmet.bodyAttributes.toString()}>
11+
<div id="root">${markup}</div>
12+
<script src="/static/js/bundle.js" async></script>
13+
</body>
14+
</html>
15+
`);

0 commit comments

Comments
 (0)