瀏覽代碼

重新修改redux写法

胡家华 5 年之前
父節點
當前提交
9e401f47f7

+ 0 - 0
index.d.ts


+ 4 - 0
package.json

@@ -8,6 +8,8 @@
8 8
     "@types/react-redux": "^6.0.3",
9 9
     "@types/react-router-dom": "^4.2.7",
10 10
     "@types/redux": "^3.6.0",
11
+    "@types/redux-logger": "^3.0.7",
12
+    "@types/redux-thunk": "^2.1.0",
11 13
     "autoprefixer": "7.1.6",
12 14
     "babel-jest": "^22.1.0",
13 15
     "babel-loader": "^7.1.2",
@@ -40,7 +42,9 @@
40 42
     "react-router": "^4.3.1",
41 43
     "react-router-dom": "^4.3.1",
42 44
     "redux": "^4.0.0",
45
+    "redux-logger": "^3.0.6",
43 46
     "redux-persist": "^5.10.0",
47
+    "redux-thunk": "^2.3.0",
44 48
     "resolve": "1.6.0",
45 49
     "source-map-loader": "^0.2.1",
46 50
     "style-loader": "0.19.0",

+ 1 - 1
src/App.tsx

@@ -2,8 +2,8 @@ import * as React from 'react'
2 2
 import { Provider } from 'react-redux'
3 3
 import { PersistGate } from 'redux-persist/integration/react'
4 4
 import './App.css'
5
-import { AppContainer } from './redux'
6 5
 import { persistor, store } from './redux/store'
6
+import AppContainer from './views/Appcontainer'
7 7
 
8 8
 class App extends React.Component {
9 9
     public render(): JSX.Element {

+ 3 - 2
src/component/showValue/index.tsx

@@ -1,8 +1,8 @@
1 1
 import * as React from 'react'
2
-import { store } from '../../redux/store'
3 2
 
4 3
 interface IShowValueProps{
5 4
     handleChange: object
5
+    value: number | string
6 6
 }
7 7
 interface IShowValueState {
8 8
     handleChangeCB: any
@@ -18,9 +18,10 @@ export default class ShowValue extends React.Component<IShowValueProps, IShowVal
18 18
     }
19 19
     public render (): JSX.Element {
20 20
         const { handleChangeCB } = this.state
21
+        const { value } = this.props
21 22
         return (
22 23
             <div className="showValue">
23
-                <input type="text" className="showValue_input" value={store.getState().count} onChange={handleChangeCB}/>
24
+                <input type="text" className="showValue_input" value={value} onChange={handleChangeCB}/>
24 25
             </div>
25 26
         )
26 27
     }

+ 2 - 0
src/redux/action/actionType.ts

@@ -0,0 +1,2 @@
1
+
2
+export const SAVECOUNT = 'SAVECOUNT'

+ 8 - 0
src/redux/action/index.ts

@@ -0,0 +1,8 @@
1
+import * as actionType from './actionType'
2
+
3
+
4
+export function saveCount (value: string | number){
5
+    return (dispatch: any) => {
6
+        dispatch({ type: actionType.SAVECOUNT, payload: { count: value } })
7
+    }
8
+}

+ 0 - 17
src/redux/action/index.tsx

@@ -1,17 +0,0 @@
1
-
2
-const ACTION = {
3
-    CHANGEVALUE: (obj:any) => {
4
-        return {
5
-            type: 'CHANGEVALUE',
6
-            value: obj.value
7
-        }
8
-    },
9
-    DECREASE: {
10
-        type: 'DECREASE'
11
-    },
12
-    INCREASE: {
13
-        type: 'INCREASE'
14
-    }
15
-}
16
-
17
-export default ACTION

+ 27 - 27
src/redux/index.tsx

@@ -1,29 +1,29 @@
1
-import { connect } from 'react-redux'
2
-import appContainer from '../views/Appcontainer'
3
-import ACTION from './action'
1
+// import { connect } from 'react-redux'
2
+// import appContainer from '../views/Appcontainer'
3
+// import ACTION from './action'
4 4
 
5
-function mapStateToProps(state: any) {
6
-    // 这里将会把 strore 中的initState映射到组件的props上
7
-    return {
8
-        count: state.count
9
-    }
10
-}
5
+// function mapStateToProps(state: any) {
6
+//     // 这里将会把 strore 中的initState映射到组件的props上
7
+//     return {
8
+//         count: state.count
9
+//     }
10
+// }
11 11
 
12
-function mapDispatchToProps(dispatch: (obj: any) => void) {
13
-    return {
14
-        // CHANGEVALUE, DECREASE, INCREASE这些函数名会映射到被连接的组件props上
15
-        CHANGEVALUE: (obj:any) => {
16
-            // 当连接redux的组件调用props上的CHANGEVALUE方法时,此处将分发对应的Action,Action在redux/action/index.tsx中维护
17
-            // 找到reducers中相匹配的action,然后执行定义的方法
18
-            dispatch(ACTION.CHANGEVALUE(obj))
19
-        },
20
-        DECREASE: () => {
21
-            dispatch(ACTION.DECREASE)
22
-        },
23
-        INCREASE: () => {
24
-            dispatch(ACTION.INCREASE)
25
-        }
26
-    }
27
-}
28
-// 此处将连接好的组件导出
29
-export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(appContainer)
12
+// function mapDispatchToProps(dispatch: (obj: any) => void) {
13
+//     return {
14
+//         // CHANGEVALUE, DECREASE, INCREASE这些函数名会映射到被连接的组件props上
15
+//         CHANGEVALUE: (obj:any) => {
16
+//             // 当连接redux的组件调用props上的CHANGEVALUE方法时,此处将分发对应的Action,Action在redux/action/index.tsx中维护
17
+//             // 找到reducers中相匹配的action,然后执行定义的方法
18
+//             dispatch(ACTION.CHANGEVALUE(obj))
19
+//         },
20
+//         DECREASE: () => {
21
+//             dispatch(ACTION.DECREASE)
22
+//         },
23
+//         INCREASE: () => {
24
+//             dispatch(ACTION.INCREASE)
25
+//         }
26
+//     }
27
+// }
28
+// // 此处将连接好的组件导出
29
+// export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(appContainer)

+ 20 - 0
src/redux/reducers/index.ts

@@ -0,0 +1,20 @@
1
+
2
+import * as actionType from '../action/actionType'
3
+
4
+interface IInitState {
5
+    count: number
6
+}
7
+const initState = {
8
+    count: 0,
9
+}
10
+export default function reducers (state: IInitState = initState , action: any) {
11
+    switch (action.type) {
12
+        case actionType.SAVECOUNT:
13
+            return { 
14
+                ...state,
15
+                count: action.payload.count
16
+            }
17
+        default:
18
+            return { count: state.count }
19
+    }
20
+}

+ 0 - 24
src/redux/reducers/index.tsx

@@ -1,24 +0,0 @@
1
-
2
-interface IInitState {
3
-    count: number
4
-}
5
-interface IActionType {
6
-    type: string,
7
-    value: string
8
-}
9
-
10
-export default function reducers (state: IInitState , action: IActionType) {
11
-    switch (action.type) {
12
-        case 'INCREASE':
13
-            return { count: ++state.count }
14
-            break
15
-        case 'DECREASE':
16
-            return { count: --state.count }
17
-            break
18
-        case 'CHANGEVALUE':
19
-            return {count: action.value}
20
-            break
21
-        default:
22
-            return { count: state.count }
23
-    }
24
-}

+ 7 - 6
src/redux/store/index.tsx

@@ -1,18 +1,19 @@
1
-import { createStore } from 'redux'
1
+import { applyMiddleware, createStore } from 'redux'
2
+import { createLogger } from 'redux-logger'
2 3
 import * as persist from 'redux-persist'
3
-import storage from 'redux-persist/lib/storage'
4 4
 import reducer from '../reducers'
5
+import storage from 'redux-persist/lib/storage'
6
+
7
+import thunkMiddleware from 'redux-thunk'
5 8
 
9
+const loggerMiddleware = createLogger()
6 10
 const { persistStore, persistReducer } = persist
7 11
 
8 12
 const persistConfig = {
9 13
     key: 'root',
10 14
     storage,
11
-  }
12
-const initState = {
13
-    count: 0
14 15
 }
15 16
 const persistedReducer = persistReducer(persistConfig, reducer)
16
-export const store = createStore(persistedReducer, initState)
17
+export const store = createStore(persistedReducer, applyMiddleware(loggerMiddleware, thunkMiddleware))
17 18
 export const persistor  = persistStore(store)
18 19
 

+ 10 - 10
src/routes/index.tsx

@@ -2,25 +2,25 @@ import * as React from 'react'
2 2
 import * as Loadable from 'react-loadable'
3 3
 
4 4
 interface IRoute {
5
-    component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>,
5
+    component: any
6 6
     path: string
7 7
 }
8 8
 
9 9
 export const route:IRoute[] = [
10 10
     {
11
-        component: import('../views/Support'),
11
+        component: loadable({ loader: () => import('../views/Support') }),
12 12
         path: '/support'
13 13
     },
14 14
     {
15
-        component: import('../views/about'),
15
+        component: loadable({ loader: () => import('../views/About') }),
16 16
         path: '/about'
17 17
     },
18 18
     {
19
-        component: import('../views/services'),
19
+        component: loadable({ loader: () => import('../views/Services') }),
20 20
         path: '/services'
21 21
     },
22 22
     {
23
-        component: import('../views/ReduxTest'),
23
+        component: loadable({ loader: () => import('../views/ReduxTest') }),
24 24
         path: '/ReduxText'
25 25
     }
26 26
 ]
@@ -36,12 +36,12 @@ function Loading(props: any) {
36 36
         return <div>loading</div>
37 37
     }
38 38
 }
39
-
40
-export const loadable = (component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>) => {
39
+ function loadable (opt: any) {
41 40
      return Loadable({
42
-        delay: 200,
43
-        loader: () => component,
41
+        delay: 300,
42
+        // loader: () => import('../views/ReduxTest'),
44 43
         loading: Loading,
45
-        timeout: 10000,
44
+        ...opt
46 45
     })
47 46
 }
47
+

+ 6 - 16
src/views/Appcontainer/index.tsx

@@ -1,30 +1,20 @@
1 1
 
2
-import * as PropTypes from 'prop-types'
3 2
 import * as React from 'react'
4
-import { HashRouter as Router, Route } from 'react-router-dom'
3
+import { HashRouter as Router, Route, RouteComponentProps } from 'react-router-dom'
5 4
 import Nav from '../../component/nav'
6
-import { loadable, route } from '../../routes'
7
-import Home from '../home'
5
+import { route } from '../../routes'
6
+import Home from '../Home'
8 7
 
9 8
 interface IRouteItem {
10
-    component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>,
9
+    component: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>
11 10
     path: string
12 11
 }
13 12
 
14 13
 export default class Appcontainer extends React.Component<any, any>{
15
-    // childContextTypes属性,声明给子孙组件提供的属性
16
-     public static childContextTypes = {
17
-        store: PropTypes.object
18
-      }
14
+
19 15
     constructor (props:any) {
20 16
         super(props)
21 17
     }
22
-    // 这个方法给子组件设置context的值,值为当前组件的props
23
-    public getChildContext () {
24
-        return {
25
-            store: this.props
26
-        }
27
-    }
28 18
     public render ():JSX.Element {
29 19
         return (
30 20
             <Router>
@@ -34,7 +24,7 @@ export default class Appcontainer extends React.Component<any, any>{
34 24
                     {
35 25
                         route.map((item:IRouteItem, index:number) => {
36 26
                             return (
37
-                                <Route path={item.path} component={loadable(item.component)} key={index}/>
27
+                                <Route path={item.path} component={item.component} key={index}/>
38 28
                             )
39 29
                         })
40 30
                     }

+ 19 - 22
src/views/ReduxTest/index.tsx

@@ -1,45 +1,35 @@
1
-import * as PropTypes from 'prop-types'
2 1
 import * as React from 'react'
2
+import { connect } from 'react-redux'
3 3
 import DecreaseBtn from '../../component/decreaseBtn'
4 4
 import IncreaseBtn from '../../component/increaseBtn'
5 5
 import NowValue from '../../component/showValue'
6 6
 import './index.less'
7 7
 
8
-export default class Counter extends React.Component<any, any> {
9
-    // 声明静态属性 contextTypes 才能访问顶层组件定义的context,属性名字也需要和父组件一样,否则访问不到值
10
-    public static contextTypes = {
11
-        store: PropTypes.object
8
+class Counter extends React.Component<any, any> {
9
+    public handleDecreaseCB = () => {
10
+        let { count } = this.props
11
+        this.props.saveCount({ count: --count })
12 12
     }
13
-    constructor (props:any) {
14
-        super(props)
15
-        this.handleDecreaseCB = this.handleDecreaseCB.bind(this)
16
-        this.handleIncreaseCB = this.handleIncreaseCB.bind(this)
17
-        this.handleChangeCB = this.handleChangeCB.bind(this)
13
+    public handleIncreaseCB = () => {
14
+        let { count } = this.props
15
+        this.props.saveCount({ count: ++count })
18 16
     }
19
-    public handleDecreaseCB () {
20
-        this.context.store.DECREASE()
21
-    }
22
-    public handleIncreaseCB () {
23
-        this.context.store.INCREASE()
24
-    }
25
-    public handleChangeCB (e: any) {
17
+    public handleChangeCB = (e: any) => {
26 18
         const val = e.target.value
27 19
         const reg = /^[0-9]*$/
28 20
         if (!reg.test(val)) {
29 21
             alert('只能输入数字')
30 22
             return
31 23
         }
32
-        this.context.store.CHANGEVALUE({
33
-            type: 'CHANGEVALUE',
34
-            value: val
35
-        })
24
+        this.props.saveCount({ count: val })
36 25
     }
37 26
     public render () {
27
+        const { count } = this.props
38 28
         return (
39 29
             <div className="container">
40 30
                 <div className="container_count">
41 31
                     <DecreaseBtn handleDecrease={this.handleDecreaseCB}/>
42
-                    <NowValue handleChange={this.handleChangeCB}/>
32
+                    <NowValue value={count} handleChange={this.handleChangeCB}/>
43 33
                     <IncreaseBtn handleIncrease={this.handleIncreaseCB}/>
44 34
                     {this.props.children}
45 35
                 </div>
@@ -47,3 +37,10 @@ export default class Counter extends React.Component<any, any> {
47 37
         )    
48 38
     }
49 39
 }
40
+
41
+export default connect(
42
+    (state: any) => ({ count: state.count }),
43
+    {
44
+        saveCount: (payload: any) => ({ type: 'SAVECOUNT', payload }),
45
+    }
46
+)(Counter)

+ 2 - 1
tslint.json

@@ -7,6 +7,7 @@
7 7
     ]
8 8
   },
9 9
   "rules": {
10
-      "no-console":false
10
+      "no-console":false,
11
+      "ordered-imports": false
11 12
     }
12 13
 }

+ 52 - 1
yarn.lock

@@ -74,6 +74,20 @@
74 74
   dependencies:
75 75
     csstype "^2.2.0"
76 76
 
77
+"@types/redux-logger@^3.0.7":
78
+  version "3.0.7"
79
+  resolved "https://registry.yarnpkg.com/@types/redux-logger/-/redux-logger-3.0.7.tgz#163f6f6865c69c21d56f9356dc8d741718ec0db0"
80
+  integrity sha512-oV9qiCuowhVR/ehqUobWWkXJjohontbDGLV88Be/7T4bqMQ3kjXwkFNL7doIIqlbg3X2PC5WPziZ8/j/QHNQ4A==
81
+  dependencies:
82
+    redux "^3.6.0"
83
+
84
+"@types/redux-thunk@^2.1.0":
85
+  version "2.1.0"
86
+  resolved "https://registry.yarnpkg.com/@types/redux-thunk/-/redux-thunk-2.1.0.tgz#bc2b6e972961831afb82a9bf4f06726e351f9416"
87
+  integrity sha1-vCtulylhgxr7gqm/TwZybjUflBY=
88
+  dependencies:
89
+    redux-thunk "*"
90
+
77 91
 "@types/redux@^3.6.0":
78 92
   version "3.6.0"
79 93
   resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.0.tgz#f1ebe1e5411518072e4fdfca5c76e16e74c1399a"
@@ -1975,6 +1989,11 @@ decode-uri-component@^0.2.0:
1975 1989
   version "0.2.0"
1976 1990
   resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
1977 1991
 
1992
+deep-diff@^0.3.5:
1993
+  version "0.3.8"
1994
+  resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
1995
+  integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=
1996
+
1978 1997
 deep-equal@^1.0.1:
1979 1998
   version "1.0.1"
1980 1999
   resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@@ -4316,6 +4335,11 @@ lodash-es@^4.17.5:
4316 4335
   version "4.17.10"
4317 4336
   resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"
4318 4337
 
4338
+lodash-es@^4.2.1:
4339
+  version "4.17.14"
4340
+  resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.14.tgz#12a95a963cc5955683cee3b74e85458954f37ecc"
4341
+  integrity sha512-7zchRrGa8UZXjD/4ivUWP1867jDkhzTG2c/uj739utSd7O/pFFdxspCemIFKEEjErbcqRzn8nKnGsi7mvTgRPA==
4342
+
4319 4343
 lodash._reinterpolate@~3.0.0:
4320 4344
   version "3.0.0"
4321 4345
   resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@@ -4377,6 +4401,11 @@ lodash.uniq@^4.5.0:
4377 4401
   version "4.17.10"
4378 4402
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
4379 4403
 
4404
+lodash@^4.2.1:
4405
+  version "4.17.14"
4406
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
4407
+  integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
4408
+
4380 4409
 loglevel@^1.4.1:
4381 4410
   version "1.6.1"
4382 4411
   resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
@@ -5879,10 +5908,22 @@ reduce-function-call@^1.0.1:
5879 5908
   dependencies:
5880 5909
     balanced-match "^0.4.2"
5881 5910
 
5911
+redux-logger@^3.0.6:
5912
+  version "3.0.6"
5913
+  resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf"
5914
+  integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8=
5915
+  dependencies:
5916
+    deep-diff "^0.3.5"
5917
+
5882 5918
 redux-persist@^5.10.0:
5883 5919
   version "5.10.0"
5884 5920
   resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b"
5885 5921
 
5922
+redux-thunk@*, redux-thunk@^2.3.0:
5923
+  version "2.3.0"
5924
+  resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
5925
+  integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
5926
+
5886 5927
 redux@*, redux@^4.0.0:
5887 5928
   version "4.0.0"
5888 5929
   resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.0.tgz#aa698a92b729315d22b34a0553d7e6533555cc03"
@@ -5890,6 +5931,16 @@ redux@*, redux@^4.0.0:
5890 5931
     loose-envify "^1.1.0"
5891 5932
     symbol-observable "^1.2.0"
5892 5933
 
5934
+redux@^3.6.0:
5935
+  version "3.7.2"
5936
+  resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b"
5937
+  integrity sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==
5938
+  dependencies:
5939
+    lodash "^4.2.1"
5940
+    lodash-es "^4.2.1"
5941
+    loose-envify "^1.1.0"
5942
+    symbol-observable "^1.0.3"
5943
+
5893 5944
 regenerate@^1.2.1:
5894 5945
   version "1.4.0"
5895 5946
   resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
@@ -6719,7 +6770,7 @@ sw-toolbox@^3.4.0:
6719 6770
     path-to-regexp "^1.0.1"
6720 6771
     serviceworker-cache-polyfill "^4.0.0"
6721 6772
 
6722
-symbol-observable@^1.2.0:
6773
+symbol-observable@^1.0.3, symbol-observable@^1.2.0:
6723 6774
   version "1.2.0"
6724 6775
   resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
6725 6776