Redux

Work flow

Redux Basis

React Redux Basis

Work flow of redux

redux work flow

Redux 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
69
70
71
72
73
74
75
76
import {createStore, combineReducers, applyMiddleware} from 'redux'
import ReduxThunk from 'redux-thunk'
import { composeWithDevTools} from 'redux-devtools-extension'

const initialState = {
count: 0
}

const userInitialState = {
username: 'john'
}



const ADD = 'ADD'
function counterReducer(state = initialState, action) {
console.log(state, action)
switch (action.type) {
case ADD:
return {count: state.count + (action.num || 1) }
default:
return state
}
}
const UPDATE_NAME = 'UPDATE_NAME'
function userReducer(state= userInitialState, action) {
switch(action.type) {
case UPDATE_NAME:
return {...state, username: action.name}
default:
return state
}
}

const allReducers = combineReducers({
counter: counterReducer,
user: userReducer
})
// createStore(reducer, [preloadedState], [enhancer])
const store = createStore(allReducers,
{
counter: initialState,
user: userInitialState
},
composeWithDevTools(applyMiddleware(ReduxThunk)) //执行异步dispatch,异步action, 和一个有效的redux调试工具
);

// action create
function add(num) {
return {
type: ADD,
num,
}
}

//
function addAsync(num) {
return (dispatch, getState) => setTimeout(()=>{
dispatch(add(num))
}, 1000)
}

console.log(store.getState())
store.dispatch({type: ADD})
console.log(store.getState())

store.subscribe(()=>{
console.log('changed', store.getState())
})

store.dispatch(add(3))
// store.dispatch({type: ADD})
store.dispatch(addAsync(5))
store.dispatch({type: UPDATE_NAME, name: 'Yehya'})

export default store

React Redux

in _app.js

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
import App, {Container} from 'next/app'
import { Provider } from 'react-redux'

import 'antd/dist/antd.css'
import Layout from "../components/Layout";
import '../styles.css'
import MyContext from '../lib/my-context'
import store from '../store/store'

class MyApp extends App {
state = {
context: 'value'
}
static async getInitialProps({Component, ctx}) {
console.log('init app')
let pageProps = {}
if(Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)

}
return {
pageProps
}

}

render() {
const {Component, pageProps} = this.props//每个页面渲染的时候都会作为Component
return (
<Container>
<Layout>
<Provider store={store}>
<MyContext.Provider value={this.state.context}>
<Component {...pageProps}/>
<button onClick={()=>this.setState({context:`${this.state.context}111`})}>update context</button>
</MyContext.Provider>
</Provider>
</Layout>
</Container>
)
}
}

export default MyApp

we import store.

In index.js

1
2
3
4
5
6
7
8
9
10
11
export default connect(function mapStateToProps(state) {
return {
counter: state.counter.count,//exposed by createStore
username: state.user.username
}
}, function mapDispatchToProps(dispatch) {
return {
add: (num)=> dispatch({ type: 'ADD', num}),
rename: (name) => dispatch({type: 'UPDATE_NAME', name})
}
})(Index)

store创建,connect 用法, redux实现flux数据流向 通过点击button 触发 action,action调用reducer,更新state,传递给provider,进入react