一、概念
1.文档:https://www.redux.org.cn/
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
2.redux的作用:处理应用的共享数据。以有条理的方式存储数据,使我们能够在应用的任何组件中快速获取该数据。
3.redux的工作流程:
(1)用户触发action(store.dispatch(action))
(2)Store 调用 Reducer,并且传入两个参数:当前 State 和收到的 Action。 Reducer 会返回新的 State 。
(State:如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。)
(3)通过store.subscribe()监听,一旦 State 发生变化,就自动执行这个函数。
(4)通过store.getState()获取新的state值
二、redux基础Demo
1.通过createStore(reducer)创建store,
2.当点击按钮时使用store.dispatch(action)触发action,store中自动调用reducer,返回新的state
3.使用store.subscribe(fun)监听是否返回新的state,若有,则执行fun
4.视图中通过store.getState()获取state值。
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux'
import reducer from './reducers/count'
// 创建store
const store = createStore(reducer);
const render = ()=> {
ReactDOM.render(
<React.StrictMode>
{/* 当点击按钮时触发action */}
<App
count={store.getState()}
onIncrement={() => store.dispatch({type:'INCREMENT'})}
onDecrement={() => store.dispatch({type:'DECREMENT'})} />
</React.StrictMode>,
document.getElementById('root')
);
}
// 加载时载入App
render();
// 当store中数据变化时重新渲染App
store.subscribe(render);
serviceWorker.unregister();
App.js:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div>
<p>{this.props.count}</p>
<button onClick={this.props.onIncrement}>加1</button>
<button onClick={this.props.onDecrement}>减1</button>
</div>
);
}
}
export default App;
reducers/count.js:
function count(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state = state + 1;
case 'DECREMENT':
return state = state - 1;
default:
return state;
}
}
export default count;
三、react-redux基础Demo
1.createStore(reducer)创建store;
2. <Provider>关联react和store,使react中能使用store;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux'
import rootReducer from './reducers/index'
import {Provider} from 'react-redux'
// 创建store
const store = createStore(rootReducer);
ReactDOM.render(
<React.StrictMode>
{/* <Provider>用来关联react和store,使react中能使用store */}
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
3.创建constants/index.js存储函数名
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
4.创建actions/counter写action
import * as actions from '../constants/index'
export function increment(num) {
return {
type: actions.INCREMENT,
num
}
}
export function decrement(num) {
return {
type: actions.DECREMENT,
num
}
}
5.创建reducers/count.js写reducer:
import * as actions from '../constants/index'
function count(state = 0, action) {
switch (action.type) {
case actions.INCREMENT:
return state = state + action.num;
case actions.DECREMENT:
return state = state - action.num;
default:
return state;
}
}
export default count;
6.创建reducers/index.js,使用combineReducers()合并reducer
import {combineReducers} from "redux"
import counter from './counter'
const rootReducer = combineReducers({
counter
})
export default rootReducer
7.使用connect():关联mapStateToProps、mapDispatchToProps和App组件,使得组件中的props可获取到mapStateToProps、mapDispatchToProps中的返回值;
8.使用bindActionCreators()组合action和dispatch生成mapDispatchToProps的返回值;
App.js:
import React, { Component } from 'react';
import './App.css';
import {connect} from 'react-redux'
import * as counterActions from './actions/counter'
import {bindActionCreators} from 'redux'
class App extends Component {
render() {
console.log(this.props)
return (
<div>
<p>{this.props.counter}</p>
<button onClick={() => this.props.counterActions.increment(10)}>加1</button>
<button onClick={() => this.props.counterActions.decrement(5)}>减1</button>
</div>
);
}
}
// 创建mapStateToProps:返回state对象映射到props的值
const mapStateToProps = (state) => {
return {
counter: state
}
}
// 创建mapDispatchToProps:返回state对象映射到props的方法
// const mapDispatchToProps = (dispatch) => {
// return {
// increment: () => dispatch(increment()),
// decrement: () => dispatch(decrement())
// }
// }
// bindActionCreators的作用是将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容。
const mapDispatchToProps = (dispatch) => {
return {
counterActions: bindActionCreators(counterActions, dispatch)
}
}
// connect():关联mapStateToProps、mapDispatchToProps和App组件。
// 在App组件中可在this.props获取到mapStateToProps、mapDispatchToProps中的返回值
export default connect(mapStateToProps,mapDispatchToProps)(App);
四、react-redux调试工具(redux-devools + redux-devtools-extension)
1.在chrome中找到redux-devools扩展程序,
2.安装redux-devtools-extension:
cnpm i --save redux-devtools-extension
3.在index.js中composeWithDevTools()关联中间件:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Provider} from 'react-redux';
import {createStore,applyMiddleware} from 'redux';
import rootReducer from './reducers/index'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
const store = createStore(rootReducer, {}, composeWithDevTools(applyMiddleware(logger,thunk)));
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();