绑定并转换action
的方法。
先看源码:
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
const boundActionCreators = {}
for (const key in actionCreators) {
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
整个源码并不多,看起来就是遍历actions
并绑定,再将dispatch
传入。
为了更方便理解,我们需要结合DEMO深入理解:
// userActions.js
export const f1 = function (id) {
return function (dispatch: any, getState: any) {
console.log('f1');
request({ id });
return getState();
};
};
export const f2 = function (id) {
return function (dispatch: any, getState: any) {
console.log('f1');
request({ id });
return getState();
};
};
引入:
// connect.js
import * as usersActions from './userActions'
function defaultMapStateToProps(state) {
return {
$user: state.user,
};
}
function defaultMapDispatchToProps(dispatch: any) {
return {
actions: {
$user: bindActionCreators(Object.assign({}, usersActions), dispatch),
}
}
}
export default function createContainer() {
const curMapStateToProps: any = defaultMapStateToProps;
const curMapDispatchToProps: any = defaultMapDispatchToProps;
return function connectAppScreen(constructor) {
return connect(curMapStateToProps, curMapDispatchToProps)(constructor);
}
}
在react组件调用action
:
@connect
class App extends React.Component {
fetch(){
this.props.$actions.$user.f1('id1')
}
}
最小化代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}
function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
const boundActionCreators = {}
for (const key in actionCreators) {
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
const dispatch = function(action) {
console.log('dispatch.action', action);
return action;
}
const actions = {
f1: (params) => {
return (dispatch) => {
console.log('f1.params', params)
dispatch({type: 'F1', payload: 'f1'})
}
},
f2: (params) => {
return (dispatch) => {
console.log('f2.params', params)
dispatch({type: 'F2', payload: 'f2'})
}
}
}
const a1 = bindActionCreators(actions, func => func(dispatch));
console.log('a1', a1)
a1.f1('xx f1');
a1.f2('bb f2');
</script>
</body>
</html>