Skip to content

Commit 49e2fbb

Browse files
committed
添加redux的例子
1 parent b3f7516 commit 49e2fbb

File tree

15 files changed

+1707
-2
lines changed

15 files changed

+1707
-2
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//.babelrc
2+
{
3+
"presets": [
4+
"react",
5+
"es2015"
6+
]
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function increaseAction() {
2+
return {type: 'increase'};
3+
}
4+
5+
export function multiAction() {
6+
return {type: 'multi'};
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
import {ButtonGroup, Button} from 'react-bootstrap';
3+
class About extends React.Component {
4+
render() {
5+
return (
6+
<div>
7+
<h2>关于</h2>
8+
<ButtonGroup vertical block>
9+
<Button>Full width button</Button>
10+
<Button>Full width button</Button>
11+
</ButtonGroup>
12+
<div>Hello World!</div>
13+
</div>
14+
)
15+
}
16+
}
17+
module.exports = About;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React from 'react';
2+
import {BrowserRouter as Router, Route, Link, Redirect, HashRouter} from 'react-router-dom'
3+
import {createBrowserHistory, createHashHistory} from 'history'
4+
const history = createHashHistory()
5+
//引入组件
6+
import Home from "./home.jsx";
7+
import Topics from "./topics.jsx";
8+
import About from "./about.jsx";
9+
import {ButtonGroup, Button} from 'react-bootstrap';
10+
11+
import {increaseAction, multiAction} from '../action.js';
12+
13+
import {connect} from 'react-redux';
14+
15+
import {Tab, Tabs} from 'react-bootstrap';
16+
17+
// React component
18+
class Basic extends React.Component {
19+
constructor(props) {
20+
super(props);
21+
// 设置 initial state
22+
this.state = {
23+
text: props.initialValue || 'Hello Wscats'
24+
};
25+
// ES6 类中函数必须手动绑定
26+
this.handleSubmit = this.handleSubmit.bind(this);
27+
}
28+
handleSubmit(event) {
29+
var page = event.target.id.charAt(event.target.id.length - 1);
30+
switch (page) {
31+
case "1":
32+
history.push('/');
33+
break;
34+
case "2":
35+
history.push('/about');
36+
break;
37+
case "3":
38+
history.push('/topics');
39+
break;
40+
}
41+
}
42+
render() {
43+
const {value, onIncreaseClick} = this.props
44+
return (
45+
<HashRouter history={history}>
46+
<div>
47+
<Tabs defaultActiveKey={2} id="uncontrolled-tab-example" onClick={this.handleSubmit}>
48+
<Tab eventKey={1} title="Tab 1"></Tab>
49+
<Tab eventKey={2} title="Tab 2"></Tab>
50+
<Tab eventKey={3} title="Tab 3" disabled></Tab>
51+
</Tabs>
52+
<p>{value}</p>
53+
<button onClick={onIncreaseClick}>Increase</button>
54+
<ul>
55+
<li>
56+
<Link to="/">首页</Link>
57+
</li>
58+
<li>
59+
<Link to="/about">关于</Link>
60+
</li>
61+
<li>
62+
<Link to="/topics">主题列表</Link>
63+
</li>
64+
</ul>
65+
<hr/>
66+
<Route exact path="/" component={Home}/>
67+
<Route path="/about" component={About}/>
68+
<Route path="/topics" component={Topics}/>
69+
<Redirect to="/topics"/>{/*默认跳转*/}
70+
</div>
71+
</HashRouter>
72+
)
73+
}
74+
}
75+
76+
// Map Redux state to component props
77+
function mapStateToProps(state) {
78+
return {value: state.count}
79+
}
80+
81+
// Map Redux actions to component props
82+
function mapDispatchToProps(dispatch) {
83+
return {
84+
onIncreaseClick: () => {
85+
//可以触发多个
86+
dispatch(increaseAction())
87+
dispatch(multiAction())
88+
}
89+
}
90+
}
91+
// Connected Component
92+
export default connect(mapStateToProps, mapDispatchToProps)(Basic);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var React = require('react');
2+
class ProductBox extends React.Component {
3+
render() {
4+
return(
5+
<div>Hello World!</div>
6+
)
7+
}
8+
}
9+
module.exports = ProductBox;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react';
2+
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
3+
4+
import {connect} from 'react-redux';
5+
6+
import {increaseAction, multiAction} from '../action.js';
7+
8+
const Topic = ({match}) => (
9+
<div>
10+
<h3>{match.params.topicId}</h3>
11+
</div>
12+
)
13+
class Topics extends React.Component {
14+
render() {
15+
const {value, onIncreaseClick} = this.props;
16+
return (
17+
<div>
18+
<h2>主题列表</h2>
19+
<p>{value}</p>
20+
<button onClick={onIncreaseClick}>Increase</button>
21+
<ul>
22+
<li>
23+
<Link to="/topics/rendering">
24+
使用 React 渲染
25+
</Link>
26+
</li>
27+
<li>
28+
<Link to="/topics/components">
29+
组件
30+
</Link>
31+
</li>
32+
<li>
33+
<Link to="/topics/props-v-state">
34+
属性 v. 状态
35+
</Link>
36+
</li>
37+
</ul>
38+
<Route path="/topics/:topicId" component={Topic}/>
39+
<Route exact path="/topics" render={() => (
40+
<h3>请选择一个主题。</h3>
41+
)}/>
42+
</div>
43+
)
44+
}
45+
}
46+
47+
// Map Redux state to component props
48+
function mapStateToProps(state) {
49+
return {value: state.count}
50+
}
51+
52+
// Map Redux actions to component props
53+
function mapDispatchToProps(dispatch) {
54+
return {
55+
onIncreaseClick: () => {
56+
//可以触发多个
57+
dispatch(increaseAction())
58+
dispatch(multiAction())
59+
}
60+
}
61+
}
62+
63+
// Connected Component 让Topics也连接上store
64+
module.exports = connect(mapStateToProps, mapDispatchToProps)(Topics);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import Basic from "./components/basic.jsx";
4+
5+
//redux
6+
import {Provider, connect} from 'react-redux';
7+
import {createStore} from 'redux';
8+
9+
//模块化action,方便在组件中调用
10+
import {increaseAction, multiAction} from './action.js';
11+
//模块化reducer
12+
import counter from './reducer.js';
13+
14+
// Store
15+
const store = createStore(counter);
16+
17+
// Action
18+
// const increaseAction = {
19+
// type: 'increase'
20+
// }
21+
//
22+
// const multiAction = {
23+
// type: 'multi'
24+
// }
25+
26+
// Reducer
27+
// function counter(state = {
28+
// count: 0
29+
// }, action) {
30+
// const count = state.count
31+
// switch (action.type) {
32+
// case 'increase':
33+
// return {
34+
// count: count + 2
35+
// }
36+
// case 'multi':
37+
// return {
38+
// count: count * 2
39+
// }
40+
// default:
41+
// return state
42+
// }
43+
// }
44+
45+
// 放在Basic入面connect
46+
// // Map Redux state to component props
47+
// function mapStateToProps(state) {
48+
// return {value: state.count}
49+
// }
50+
//
51+
// // Map Redux actions to component props
52+
// function mapDispatchToProps(dispatch) {
53+
// return {
54+
// onIncreaseClick: () => {
55+
// //可以触发多个
56+
// dispatch(increaseAction())
57+
// dispatch(multiAction())
58+
// }
59+
// }
60+
// }
61+
62+
// Connected Component
63+
//const App = connect(mapStateToProps, mapDispatchToProps)(Basic)
64+
65+
ReactDOM.render((
66+
<Provider store={store}>
67+
<Basic/>
68+
</Provider>
69+
), document.getElementById('root'))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export default function counter(state = {
2+
count: 0
3+
}, action) {
4+
const count = state.count
5+
switch (action.type) {
6+
case 'increase':
7+
return {
8+
count: count + 2
9+
}
10+
case 'multi':
11+
return {
12+
count: count * 2
13+
}
14+
default:
15+
return state
16+
}
17+
}

react+webpack+react-router+redux/build/bundle.js

Lines changed: 1350 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head lang="en">
5+
<meta charset="UTF-8">
6+
<title>React Test</title>
7+
<!-- Latest compiled and minified CSS -->
8+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
9+
<!-- Optional theme -->
10+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap-theme.min.css">
11+
</head>
12+
13+
<body>
14+
<!--要插入React组件的位置-->
15+
<div id="root"></div>
16+
<script src="bundle.js"></script>
17+
</body </html>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"devDependencies": {
3+
"babel-core": "^6.24.1",
4+
"babel-loader": "^7.0.0",
5+
"babel-preset-es2015": "^6.24.1",
6+
"babel-preset-react": "^6.24.1",
7+
"less-loader": "^4.0.3",
8+
"react": "^15.5.4",
9+
"react-dom": "^15.5.4",
10+
"react-router-dom": "^4.1.1",
11+
"style-loader": "^0.16.1",
12+
"url-loader": "^0.5.8",
13+
"webpack": "^2.4.1",
14+
"webpack-dev-server": "^2.4.2"
15+
},
16+
"dependencies": {
17+
"history": "^4.6.1",
18+
"react-bootstrap": "^0.31.0",
19+
"react-redux": "^5.0.5",
20+
"react-router-config": "^1.0.0-beta.3",
21+
"redux": "^3.6.0"
22+
}
23+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
2+
module.exports = { //注意这里是exports不是export
3+
devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map
4+
entry: __dirname + "/app/main.js", //唯一入口文件
5+
output: { //输出目录
6+
path: __dirname + "/build", //打包后的js文件存放的地方
7+
filename: 'bundle.js', //打包后的js文件名
8+
},
9+
module: {
10+
loaders: [{
11+
test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理
12+
exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选)
13+
loader: 'babel-loader'
14+
//npm install babel-loader
15+
//npm install babel-core
16+
}, {
17+
test: /\.css$/,
18+
loader: 'style-loader!css-loader'
19+
}, {
20+
test: /\.less$/,
21+
loader: 'style-loader!css-loader!less-loader'
22+
}, {
23+
test: /\.(png|jpg)$/,
24+
loader: 'url-loader?limit=25000'
25+
}]
26+
},
27+
devServer: {
28+
contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录)
29+
historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
30+
inline: true, //设置为true,当源文件改变时会自动刷新页面
31+
port: 12345, //设置默认监听端口,如果省略,默认为"8080"
32+
}
33+
};

react+webpack/app/components/root.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//var React = require('react');
22
import React, { Component } from 'react';
3-
var routes = require("../routes.js");
43
import {
54
BrowserRouter as Router,
65
Route,

react+webpack/app/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010

1111

1212
var routes = require("./routes.js");
13+
matchRoutes(routes, '/index');
1314
console.log(routes)
1415
//默认路由
1516
const branch = matchRoutes(routes, '/index')

react+webpack/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ module.exports = { //注意这里是exports不是export
2828
contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录)
2929
historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
3030
inline: true, //设置为true,当源文件改变时会自动刷新页面
31-
port: 8080, //设置默认监听端口,如果省略,默认为"8080"
31+
port: 12345, //设置默认监听端口,如果省略,默认为"8080"
3232
}
3333
};

0 commit comments

Comments
 (0)