Skip to content

Commit

Permalink
服务端渲染样式配置,引入react-helmet优化每个页面的title和description
Browse files Browse the repository at this point in the history
  • Loading branch information
neroneroffy committed Oct 14, 2018
1 parent b1d4730 commit ab12b5b
Show file tree
Hide file tree
Showing 16 changed files with 299 additions and 66 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"less-loader": "^4.1.0",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-helmet": "^5.2.0",
"react-redux": "^5.0.7",
"react-router-config": "^4.4.0-beta.1",
"react-router-dom": "^4.3.1",
Expand Down
194 changes: 175 additions & 19 deletions public/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { renderRoutes } from 'react-router-config'
import { actions } from './components/Header/store/'

const App = props => <div className="app">
<Header/>
<Header staticContext={props.staticContext}/>
{ renderRoutes(props.route.routes) }
</div>
App.loadData = store => {
Expand Down
6 changes: 0 additions & 6 deletions src/components/Header/Header.less

This file was deleted.

15 changes: 9 additions & 6 deletions src/components/Header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ import React, { Fragment, Component } from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { actions } from './store'
import styles from './index.less'
import withStyle from '../../withStyle'

class Header extends Component {

render() {
const { login, handleLogin, handleLogout } = this.props
return (
<div className="header">
<Link to='/'>首页</Link>
<div className={styles.container}>
<Link to='/' className={styles.item}>首页</Link>
{
login ? <Fragment>
<Link to='/translation'>翻译列表</Link>
<div onClick={handleLogout}>退出</div>
<Link to='/translation' className={styles.item}>翻译列表</Link>
<div onClick={handleLogout} className={styles.item}>退出</div>
</Fragment>
:
<div onClick={ handleLogin }>登陆</div>
<div onClick={ handleLogin } className={styles.item}>登陆</div>
}
</div>
)
Expand All @@ -36,4 +39,4 @@ const mapDispatchToProps = dispatch => ({
dispatch(actions.logout())
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Header)
export default connect(mapStateToProps, mapDispatchToProps)(withStyle(Header, styles))
16 changes: 16 additions & 0 deletions src/components/Header/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.container {
height: 40px;
padding-top: 9px;
box-sizing: border-box;
}
.item {
display: inline-block;
color: #333;
text-decoration: none;
margin-right: 20px;
font-size: 16px;
cursor: pointer;
&:hover {
color: #999;
}
}
6 changes: 0 additions & 6 deletions src/containers/Home/index.css

This file was deleted.

39 changes: 26 additions & 13 deletions src/containers/Home/index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
import React from 'react'
import { connect } from 'react-redux'
import { Helmet } from "react-helmet"
import { fetchHomeList } from "./store/actions";
import styles from './index.css'
import styles from './index.less'
import withStyle from '../../withStyle'


class Home extends React.Component {

componentDidMount() {
if(!this.props.list.length) {
this.props.getHomeList()
}
}
getList() {
const { list } = this.props
return <div className={styles.test}>
return <div>
{
list.map(v => <div key={v.id}>{v.title}</div>)
list.map(v => <div className={styles.item} key={v.id}>{v.title}</div>)
}
</div>
}
render() {
return <div className="home">
<div>I am {this.props.name}</div>
{this.getList()}
<button onClick={() => alert('click')}>click</button>
</div>
return <React.Fragment>
<Helmet>
<title>SSR 练习--首页</title>
<meta charSet="utf-8" name="description" content="首页的描述" />
</Helmet>
<div className={styles.container}>
{this.getList()}
</div>

</React.Fragment>
}
}
Home.loadData = store => {
// 负责在服务器端渲染的时候把当前路由所需要的数据提前加载好
return store.dispatch(fetchHomeList())
}

const mapStateToProps = state => {
return {
list: state.home.newsList,
Expand All @@ -41,4 +47,11 @@ const mapDispatchToProps = dispatch => ({
}
})

export default connect(mapStateToProps, mapDispatchToProps)(Home)
const ExportHome = connect(mapStateToProps, mapDispatchToProps)(withStyle(Home, styles))

ExportHome.loadData = store => {
// 负责在服务器端渲染的时候把当前路由所需要的数据提前加载好
return store.dispatch(fetchHomeList())
}

export default ExportHome
8 changes: 8 additions & 0 deletions src/containers/Home/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.container {
margin-top: 20px;
}
.item {
line-height: 34px;
font-size: 16px;
color: #666;
}
30 changes: 22 additions & 8 deletions src/containers/Translation/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react'
import { connect } from 'react-redux'
import { Helmet } from "react-helmet"
import { getTranslationList } from './store/actions'
import { Redirect } from 'react-router-dom'
import styles from './index.less'
import withStyle from '../../withStyle'

class Translation extends React.Component {
componentDidMount() {
Expand All @@ -12,23 +15,27 @@ class Translation extends React.Component {
const { list, login } = this.props
return login ? <div>
{
list.map(v => <div key={v.id}>{v.title}</div>)
list.map(v => <div className={styles.item} key={v.id}>{v.title}</div>)
}
</div>
:
<Redirect to='/'/>
}

render() {
return <div className="translation">
{this.getList()}
</div>
return <React.Fragment>
<Helmet>
<title>SSR 练习--翻译列表</title>
<meta charSet="utf-8" name="description" content="翻译列表的描述" />
</Helmet>

<div className={styles.container}>
{this.getList()}
</div>
</React.Fragment>
}
}

Translation.loadData = store => {
return store.dispatch(getTranslationList())
}
const mapStateToProps = state => {
return {
list: state.translation.translationList,
Expand All @@ -41,4 +48,11 @@ const mapDispatchToProps = dispatch => ({
}
})

export default connect(mapStateToProps, mapDispatchToProps)(Translation)
const ExportTranslation = connect(mapStateToProps, mapDispatchToProps)(withStyle(Translation,styles))

ExportTranslation.loadData = store => {
return store.dispatch(getTranslationList())
}


export default ExportTranslation
8 changes: 8 additions & 0 deletions src/containers/Translation/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.container {
margin-top: 20px;
}
.item {
line-height: 34px;
font-size: 16px;
color: #666;
}
7 changes: 5 additions & 2 deletions src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ app.get('*', function (req, res) {
}
})
Promise.all(promises).then(() => {
const context = {}
const context = {
css: []
}
const html = render(req, store, routes, context)
if (context.action === 'REPLACE') {
res.redirect(301, context.url)
Expand All @@ -40,7 +42,8 @@ app.get('*', function (req, res) {
} else {
res.send(html)
}
}).catch(() => {
}).catch((err) => {
console.log(err);
res.end('sorry, request error')
})
})
Expand Down
8 changes: 7 additions & 1 deletion src/server/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { renderToString } from "react-dom/server";
import { StaticRouter } from "react-router-dom";
import { renderRoutes } from 'react-router-config'
import { Provider } from 'react-redux'
import { Helmet } from "react-helmet"

export const render = (req, store, routes, context) => {
const content = renderToString((
Expand All @@ -14,10 +15,15 @@ export const render = (req, store, routes, context) => {
</StaticRouter>
</Provider>
))
const helmet = Helmet.renderStatic()

const cssStr = context.css.length ? context.css.join('\n') : ''
return `
<html>
<head>
<title>SSR</title>
${helmet.title.toString()}
${helmet.meta.toString()}
<style>${cssStr}</style>
</head>
<body>
<div id="root">${content}</div>
Expand Down
15 changes: 15 additions & 0 deletions src/withStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { Component } from 'react'

export default (DecoratedComponent, styles) => {
return class NewComponent extends Component {
componentWillMount() {
if (this.props.staticContext) {
this.props.staticContext.css.push(styles._getCss())
}
}

render() {
return <DecoratedComponent {...this.props}/>
}
}
}
5 changes: 3 additions & 2 deletions webpack.client.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const clientConfig = {
module: {
rules: [
{
test: /\.css$/,
test: /\.less$/,
use: [
'style-loader',
{
Expand All @@ -21,7 +21,8 @@ const clientConfig = {
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
}
},
'less-loader'
]
}
]
Expand Down
5 changes: 3 additions & 2 deletions webpack.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const serverConfig = {
module: {
rules: [
{
test: /\.css$/,
test: /\.less$/,
use: [
'isomorphic-style-loader',
{
Expand All @@ -24,7 +24,8 @@ const serverConfig = {
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
}
},
'less-loader'
]
}
]
Expand Down

0 comments on commit ab12b5b

Please sign in to comment.