react初体验: 使用react搭建新闻网站

近日接触了React,跟着课程用React做了一个新闻展示网站,兼容PC和移动端,项目没有对响应式进行完全的适配,主要是css方面不是重点,重点是体验React的组件化功能和组件的书写方式,以及ant design的试用。
项目地址:react_news_demo

环境搭建

根据react官网描述,最基本的框架库为reactreact-dom,后者主要是用来实现react的虚拟DOM设计方案。
react有自己的官方路由工具——react-router
关于XHR请求,fetch非常好用。
如果要兼容PC端和移动端,那么请使用react-response

构建工具为webpack,语法使用ES6,那么久要有相关的解析,React的官网已经进行了相关说明,分别为babel-loaderbabel-plugin-react-html-attrsbabel-preset-es2015babel-preset-reactbabelify

同时还有最重要的组件库,阿里出的ant design.

于是,得出了如下的package.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"name": "react_news_demo",
"version": "1.0.0",
"description": "",
"main": "route.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --hot --inline"
},
"author": "",
"license": "ISC",
"dependencies": {
"antd": "^2.7.3",
"babel-loader": "^6.3.2",
"babel-plugin-react-html-attrs": "^2.0.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.23.0",
"babelify": "^7.3.0",
"css-loader": "^0.25.0",
"fetch": "^1.1.0",
"json-loader": "^0.5.4",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-mixin": "^2.0.2",
"react-responsive": "^1.2.1",
"react-router": "^3.0.2",
"style-loader": "^0.13.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1"
},
"devDependencies": {
"babel-plugin-import": "^1.0.1"
}
}

webpack配置

配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname),
devtool: debug ? "inline-sourcemap" : null,
entry: "./src/js/route.js",
module: {
loaders: [
{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['react-html-attrs'], //添加组件的插件配置
}
},
//下面是使用 ant-design 的配置文件
{ test: /\.css$/, loader: 'style-loader!css-loader' }
]
},
output: {
path: __dirname,
filename: "./src/bundle.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};

根文件的路由配置

可以参考react-router的文档,举例demo为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from 'react'
import ReactDOM from 'react-dom'
import {Router, Route, hashHistory } from 'react-router'
//还要引用相关的组件
export default class Root extends React.Component{
render(){
return(
<div>
<Router history={hashHistory}>
<Route path="/" component={PCIndex}></Route>
<Route path="/details/:uniquekey" component={PCNewsDetails}></Route>
<Route path="/usercenter" component={PCUserCenter}></Route>
</Router>
</div>
)
}
}
ReactDOM.render(
<Root/>,
mountNode
)

组件的写法

首先引入相关的react库,引入需要的ant design组件,之后在构造函数里进行继承和state设置,在生命周期钩子函数中进行相关的函数设定,创造一些方法用于JSX里元素的调用,在render()中设置相关的变量,生成JSX。
demo如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React from 'react';
import {Row, Col} from 'antd';
import {
Menu,
Icon,
Tabs,
message,
Form,
Input,
Button,
CheckBox,
Modal,
Card,
notification
} from 'antd';
const FormItem = Form.Item;
const SubMenu = Menu.SubMenu;
const TabPane = Tabs.TabPane;
const MenuItemGroup = Menu.ItemGroup;
import {Router, Route, Link, browserHistory} from 'react-router'
class CommonComments extends React.Component {
constructor() {
super();
this.state = {
...
};
};
componentDidMount() {
...
};
handleSubmit(e) {
...
};
addUserCollection() {
...
};
render() {
let {getFieldDecorator} = this.props.form;
const {comments} = this.state;
const commentList = comments.length
?comments.map((comment,index)=>(
<Card key={index} title={comment.UserName} extra={<a href="#">发表于{comment.datetime}</a>}>
<p>{comment.Comments}</p>
</Card>
))
: '没有加载到任何评论';
return (
<div class="comment">
<Row>
<Col span={24}>
{commentList}
<Form onSubmit={this.handleSubmit.bind(this)}>
<FormItem label="您的评论">
<Input type="textarea" placeholder="写评论" {...getFieldDecorator('remark', {initialValue:''})} />
</FormItem>
<Button type="primary" htmlType="submit">提交评论</Button>
&nbsp;&nbsp;
<Button type="primary" htmlType="button" onClick={this.addUserCollection.bind(this)}>收藏该文章</Button>
</Form>
</Col>
</Row>
</div>
);
};
}
export default CommonComments = Form.create({})(CommonComments);

使用fetch进行网络请求

demo:

1
2
3
4
5
6
7
8
var myFetchOptions = {
method: 'GET'
};
fetch(url, myFetchOptions)
.then(response => response.json())
.then(json => {
//成功后的回调函数
});

Snapline wechat
扫码关注我的公众号“约翰柠檬的唱片店”
Buy me a cup of Coffee