Skip to content

Commit 1bf4279

Browse files
committed
integrate redux to the FilterableProductTable, first step show productslist
1 parent 662ba18 commit 1bf4279

File tree

8 files changed

+171
-86
lines changed

8 files changed

+171
-86
lines changed

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
"dependencies": {
66
"prop-types": "^15.6.0",
77
"react": "^15.5.4",
8-
"react-dom": "^15.5.4"
8+
"react-dom": "^15.5.4",
9+
"react-redux": "^5.0.6",
910
"react-router-dom": "^4.2.2",
11+
"redux": "^3.7.2"
1012
},
1113
"devDependencies": {
1214
"eslint": "^3.19.0",
@@ -24,8 +26,11 @@
2426
},
2527
"lint-staged": {
2628
"gitDir": "./",
27-
"linters":{
28-
"src/**/*.jsx": ["eslint --fix", "git add"]
29+
"linters": {
30+
"src/**/*.jsx": [
31+
"eslint --fix",
32+
"git add"
33+
]
2934
}
3035
},
3136
"homepage": "https://jerryni.github.io/react-redux-practice/build"

src/actions/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as types from '../constants/ActionTypes'
2+
import products from '../mock/products'
3+
4+
export const getProducts = () => {
5+
return {
6+
type: types.RECEIVE_PRODUCTS,
7+
products
8+
}
9+
}
10+
11+
export const changeText = text => dispatch => {
12+
dispatch({
13+
type: types.TEXT_CHANGE,
14+
text
15+
})
16+
}
17+
18+
export const changeInStock = isInStock => dispatch => {
19+
dispatch({
20+
type: types.INSTOCK_CHNAGE,
21+
isInStock
22+
})
23+
}

src/constants/ActionTypes.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const TEXT_CHANGE = 'TEXT_CHANGE'
2+
export const INSTOCK_CHNAGE = 'INSTOCK_CHNAGE'
3+
export const RECEIVE_PRODUCTS = 'RECEIVE_PRODUCTS'

src/index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import React from 'react'
2-
import ReactDOM from 'react-dom'
2+
import {render} from 'react-dom'
3+
import {createStore} from 'redux'
4+
import {Provider} from 'react-redux'
5+
import reducer from './reducers'
6+
// import {get} from '.reducers'
37
import App from './App.jsx'
48

5-
ReactDOM.render(
6-
<App todos={[]}/>,
9+
const store = createStore(reducer)
10+
11+
render(
12+
<Provider store={store}>
13+
<App />
14+
</Provider>,
715
document.getElementById('root')
8-
);
16+
)

src/modules/FilterableProductTable.jsx

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,45 @@
66
- ProductRow:商品行
77
**/
88
import React from 'react'
9+
import {connect} from 'react-redux'
910
import SearchBar from './SearchBar.jsx'
1011
import ProductTable from './ProductTable.jsx'
1112
import products from '../mock/products'
13+
import * as actions from '../actions/index'
14+
import * as types from '../constants/ActionTypes'
1215

1316
// import PropTypes from 'prop-types'
1417
class FilterableProductTable extends React.Component {
15-
state = {
16-
filterText: '',
17-
inStockOnly: false
18-
}
19-
handleFilterTextChange(filterText) {
20-
this.setState({
21-
filterText
22-
})
23-
}
24-
handleInStockChange(inStockOnly) {
25-
this.setState({
26-
inStockOnly
27-
})
28-
}
29-
render() {
30-
return (
31-
<div>
32-
<SearchBar
33-
filterText={this.state.filterText}
34-
inStockOnly={this.state.inStockOnly}
35-
onFilterTextChange={this.handleFilterTextChange.bind(this)}
36-
onInStockChange={this.handleInStockChange.bind(this)}/>
37-
<ProductTable
38-
products={products}
39-
filterText={this.state.filterText}
40-
inStockOnly={this.state.inStockOnly}/>
41-
</div>
42-
)
43-
}
18+
componentDidMount() {
19+
this.props.getProducts()
20+
}
21+
render() {
22+
const {filterText, isInStock, products} = this.props
23+
return (
24+
<div>
25+
<SearchBar
26+
filterText={filterText}
27+
inStockOnly={isInStock}
28+
// onFilterTextChange={this.handleFilterTextChange.bind(this)}
29+
// onInStockChange={this.handleInStockChange.bind(this)}
30+
/>
31+
<ProductTable
32+
products={products}/>
33+
</div>
34+
)
35+
}
4436
}
4537

46-
export default FilterableProductTable
38+
const mapStateToProps = store => ({
39+
products: store.products.products,
40+
filterText: store.products.filterText,
41+
inStock: store.products.isInStock
42+
})
43+
44+
const mapDispatchToProps = (dispatch) => {
45+
return {
46+
getProducts: (...args) => dispatch(actions.getProducts(...args))
47+
}
48+
}
49+
50+
export default connect(mapStateToProps, mapDispatchToProps)(FilterableProductTable)

src/modules/ProductTable.jsx

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,37 @@ import ProductCategoryRow from './subModules/ProductCategoryRow.jsx'
1010
import ProductRow from './subModules/ProductRow.jsx'
1111
import PropTypes from 'prop-types'
1212
class ProductTable extends React.Component {
13-
static propTypes = {
14-
products: PropTypes.array
15-
}
13+
static propTypes = {
14+
products: PropTypes.array
15+
}
1616

17-
static defaultProps = {
18-
products: []
19-
}
17+
static defaultProps = {
18+
products: []
19+
}
2020

21-
render() {
22-
let rows = []
23-
let lastCategory = null;
24-
const filterText = this.props.filterText;
25-
const inStockOnly = this.props.inStockOnly;
21+
render() {
22+
let { products } = this.props
23+
return (
24+
<table>
25+
<thead>
26+
<tr>
27+
<th>Name</th>
28+
<th>Price</th>
29+
</tr>
30+
</thead>
31+
<tbody>
32+
{
33+
products.map(product => {
34+
return <ProductRow
35+
product={product}
36+
key={product.name} />
37+
})
38+
}
39+
</tbody>
2640

27-
this.props.products.forEach((product) => {
28-
if(product.name.indexOf(filterText) === -1) {
29-
return;
30-
}
31-
32-
if (inStockOnly && !product.stocked) {
33-
return;
34-
}
35-
36-
if (product.category !== lastCategory) {
37-
rows.push(
38-
<ProductCategoryRow
39-
category={product.category}
40-
key={product.category} />
41-
);
42-
}
43-
rows.push(
44-
<ProductRow
45-
product={product}
46-
key={product.name} />
47-
);
48-
lastCategory = product.category;
49-
})
50-
return (
51-
<table>
52-
<thead>
53-
<tr>
54-
<th>Name</th>
55-
<th>Price</th>
56-
</tr>
57-
</thead>
58-
<tbody>
59-
{rows}
60-
</tbody>
61-
62-
</table>
63-
)
64-
}
41+
</table>
42+
)
43+
}
6544
}
6645

6746
export default ProductTable

src/reducers/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {
2+
combineReducers
3+
} from 'redux'
4+
import products from './products'
5+
6+
export default combineReducers({
7+
products
8+
})

src/reducers/products.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
combineReducers
3+
} from 'redux'
4+
import {
5+
TEXT_CHANGE,
6+
INSTOCK_CHNAGE,
7+
RECEIVE_PRODUCTS
8+
} from '../constants/ActionTypes'
9+
10+
const filteredProducts = (state = [], action) => {
11+
switch (action.type) {
12+
case TEXT_CHANGE:
13+
case INSTOCK_CHNAGE:
14+
// 这边执行过滤逻辑
15+
return state.products.filter((product) => {
16+
return product.stocked && product.name.indexOf(filterText) > -1;
17+
})
18+
default:
19+
return state
20+
}
21+
}
22+
23+
const filterText = (state = '', action) => {
24+
switch (action.type) {
25+
case TEXT_CHANGE:
26+
return action.text
27+
default:
28+
return state
29+
}
30+
}
31+
32+
const products = (state = [], action) => {
33+
switch (action.type) {
34+
case RECEIVE_PRODUCTS:
35+
return action.products
36+
default:
37+
return state
38+
}
39+
}
40+
41+
const isInStock = (state = '', action) => {
42+
switch (action.type) {
43+
case INSTOCK_CHNAGE:
44+
return action.isInStock
45+
default:
46+
return state
47+
}
48+
}
49+
50+
export default combineReducers({
51+
filteredProducts,
52+
filterText,
53+
isInStock,
54+
products
55+
})

0 commit comments

Comments
 (0)