持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
Redux 核心概念
redux流程
view --> action --> reducer --> store --> view
完整步骤。
- component组件dispatch
// 创建 store 传参数reducer
var store = Redux.createStore(reducer);
store.dispatch(action)
- Store 接收 Action 并将 Action 分发给 Reducer
- reducer根据action的type写逻辑代码,然后将更改后的state返回给store,reducer函数返回什么store就存什么,订阅方法subscribe 中就接受什么
- 组件订阅变量的状态,走订阅方法
我们以加减count为例,接受使用方法
// 2. 创建reducer
/**
* @params state : 对象{} store 里面的所有变量 此例子里面只有一个变量count { count: 0 } 所以要给state一个默认值
* @params action: { type : '', payload: {}} action 有两个参数,type 和传参payload
*
* */
function reducer(state = { count: 0 }, action){
switch (action) {
case 'increment':
return {...state, count: count + action.payload.tick};
default:
return state
}
}
// 1. 首先创建store
const store = Redux.createStore(reducer)
// 3. 创建action,
const inscrement5 = {type: 'increment', payload: { tick: 5}}
const decrement5 = {type: 'increment', payload: { tick: -5}} // 传参 -5相当于减去(decrement)tick的功能
// 4. dispatch 发送action
document.getElementById('plus').onclick = function () {
store.dispatch(inscrement5);
}
document.getElementById('mimus').onclick = function () {
store.dispatch(decrement5);
}
// 5. 订阅 store
store.subscribe(() => {
// 获取store对象中存储的状态
const{ count } = store.getState()
document.getElementById('count').innerHTML = count;
})
React中使用Redux
主要是react-redux库,让redux和react结合的更紧密。
Provider
正常情况的redux如上面例子一样,全部写在一起,若在正常项目几十上百文件中使用,首先要解决的就是store对象共享到所有文件中,于是就有了provider // index.js
import {Provider} from "react-redux";
ReactDOM.render(<Provider store={store}><App/></Provider>, document.getElementById('root'))
connect
connect高阶组件,可以将store中的state里面的变量以props形式传递给component,同时props里面还有dispatch 会帮我们订阅store 当store中的变量值发生更改的时候 会帮助我们重新渲染组件
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
//Counter.js组件
import React from 'react';
import { connect } from 'react-redux';
function Counter ({count, increment5, decrement5}) {
return <div>
<button onClick={increment5}>+</button>
<span>{count}</span>
<button onClick={decrement5}>-</button>
</div>
}
const mapStateToProps = state => ({
count: state.counter.count
});
/**
*
* connect 方法第二个参数
@return 返回对象,在mapDispatchToProps中定义的所有action在组件props里面都能直接获取到,
相当于调用`props.increment5`等价于 dispatch({type: 'increment', payload: { tick: 5}})
* */
const mapDispatchToProps = dispatch => ({
increment5 () {
dispatch({type: 'increment', payload: { tick: 5}})
},
decrease5 () {
dispatch({type: 'increment', payload: { tick: -5}})
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
综上,mapStateToProps是讲store中参数在封装组件中props中,
mapDispatchToProps 则是省略掉 dispatch({type: 'increment', payload: { tick: 5}})而是直接在props中调increment5就相当于调了dispatch
bindActionsCreators
主要作用是传入action对象
{type: 'increment', payload: { tick: -5}}帮我们加上dispatch{type: 'increment', payload: { tick: -5}}调用
优化后
//count.action.js文件
export const increment = payload => ({type: INCREMENT, payload});
export const increment5 = payload => ({type: INCREMENT5, { tick: 5}});
export const decrement5 = payload => ({type: DECREMENT5, { tick: -5}});
//Counter.js组件
import React from 'react';
import { connect } from 'react-redux';
import * as couterActions from '../store/actions/counter.actions';
//...省略代码...
/**
*
* connect 方法第二个参数
@return 返回对象,在mapDispatchToProps中定义的所有action在组件props里面都能直接获取到,
相当于调用`props.increment5`等价于 dispatch({type: 'increment', payload: { tick: 5}})
* */
const mapDispatchToProps = dispatch => (couterActions, dispatch)
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
combineReducers
将多个reducer合在一起
// root.reducer.js文件
export default combineReducers({
counter: CounterReducer,
modal: ModalReducer
})
import RootReducer from "./reducers/root.reducer";
// 创建store的时候传参更简洁
const store = createStore(RootReducer)