如何使用带 Redux 的连接从 this.props 获得简单的调度?
Posted
技术标签:
【中文标题】如何使用带 Redux 的连接从 this.props 获得简单的调度?【英文标题】:How to get simple dispatch from this.props using connect w/ Redux? 【发布时间】:2016-03-31 05:18:59 【问题描述】:我有一个简单的 React 组件,我连接起来(映射一个简单的数组/状态)。为了避免引用 store 的上下文,我想要一种直接从 props 获取“dispatch”的方法。我见过其他人使用这种方法,但由于某种原因无法访问它:)
这是我当前使用的每个 npm 依赖项的版本
"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"
这是带有连接方法的组件
class Users extends React.Component
render()
const people = this.props;
return (
<div>
<div>this.props.children</div>
<button onClick=() => this.props.dispatch(type: ActionTypes.ADD_USER, id: 4); >Add User</button>
</div>
);
;
function mapStateToProps(state)
return people: state.people ;
export default connect(mapStateToProps,
fetchUsers
)(Users);
如果您需要查看减速器(没什么令人兴奋的,但它就在这里)
const initialState =
people: []
;
export default function(state=initialState, action)
if (action.type === ActionTypes.ADD_USER)
let newPeople = state.people.concat([id: action.id, name: 'wat']);
return people: newPeople;
return state;
;
如果您需要查看我的路由器是如何使用 redux 配置的
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
const store = createStoreWithMiddleware(reducers);
var Route = (
<Provider store=store>
<Router history=createBrowserHistory()>
Routes
</Router>
</Provider>
);
更新
看起来如果我在连接中省略我自己的调度(当前在上面显示 fetchUsers),我将获得免费调度(只是不确定这是否是带有异步操作的设置通常如何工作)。人们是混搭还是全有还是全无?
[mapDispatchToProps]
【问题讨论】:
【参考方案1】:您通常可以根据自己的喜好进行混搭。
如果这是你想要的,你可以将dispatch
作为道具传递:
export default connect(mapStateToProps, (dispatch) => (
...bindActionCreators(fetchUsers, dispatch), dispatch
))(Users);
我不确定fetchUsers
是如何使用的(作为异步函数?),但你通常会使用bindActionCreators
之类的东西来自动绑定 调度,然后你就没有担心在连接的组件中直接使用dispatch
。
使用dispatch
目录可以将 dumb 无状态组件与 redux 结合起来。这会降低它的便携性。
【讨论】:
你的建议行不通。你会得到一个未绑定的fetchUsers
作为道具注入。快捷表示法仅在您将对象作为第二个参数传递时才有效。当你传递一个函数时,你必须自己调用bindActionCreators
:dispatch => ( ...bindActionCreators( fetchUsers , dispatch), dispatch )
。
为什么直接在bindActionCreators中传播和传入dispatch? dispatch => ( bindActionCreators( dispatch, fetchUsers , dispatch))
【参考方案2】:
虽然您可以将dispatch
作为dispatchToProps
的一部分向下传递,但我建议避免直接从您的组件中访问store
或dispatch
。似乎通过在连接的第二个参数dispatchToProps
中传递绑定动作创建者@
请参阅我在https://***.com/a/34455431/2644281 此处发布的示例,说明如何以这种方式传递“已绑定的动作创建者”,您的组件无需直接了解或依赖于 store/dispatch。
对不起,简短。我会更新更多信息。
【讨论】:
【参考方案3】:默认情况下mapDispatchToProps
只是dispatch => ( dispatch )
。
因此,如果您不指定 connect()
的第二个参数,您将在组件中注入 dispatch
作为道具。
如果您将自定义函数传递给mapDispatchToProps
,您可以对该函数执行任何操作。
几个例子:
// inject onClick
function mapDispatchToProps(dispatch)
return
onClick: () => dispatch(increment())
;
// inject onClick *and* dispatch
function mapDispatchToProps(dispatch)
return
dispatch,
onClick: () => dispatch(increment())
;
为了节省你的打字时间,Redux 提供了bindActionCreators()
让你可以转这个:
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch)
return
onPlusClick: () => dispatch(increment()),
onMinusClick: () => dispatch(decrement())
;
进入这个:
import bindActionCreators from 'redux';
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch)
return bindActionCreators(
onPlusClick: increment,
onMinusClick: decrement
, dispatch);
当道具名称与动作创建者名称匹配时甚至更短:
// injects increment and decrement
function mapDispatchToProps(dispatch)
return bindActionCreators( increment, decrement , dispatch);
如果您愿意,绝对可以在此处手动添加dispatch
:
// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch)
return
...bindActionCreators( increment, decrement ), // es7 spread syntax
dispatch
;
对于您是否应该这样做,没有官方建议。 connect()
通常充当 Redux-aware 和 Redux-unaware 组件之间的边界。这就是为什么我们通常觉得注入 绑定动作创建者和dispatch
是没有意义的。但是,如果您觉得需要这样做,请随意。
最后,您现在使用的模式是一个比调用bindActionCreators
更短的快捷方式。当您所做的只是返回 bindActionCreators
时,您可以省略调用,而不是这样做:
// injects increment and decrement
function mapDispatchToProps(dispatch)
return bindActionCreators( increment, decrement , dispatch);
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
可以这样写
export default connect(
mapStateToProps,
increment, decrement // injects increment and decrement
)(App);
但是,当您想要更自定义的东西时,您必须放弃那种漂亮的简短语法,例如传递 dispatch
。
【讨论】:
@DanAbramov btw 是bindActionCreators(actionCreators, dispatch)
中的第二个参数可选吗?我在// es7 spread syntax
行的代码中注意到,dispatch
没有传递给bindActionCreators
增量法里面是什么?
es7 传播语法应该是function mapDispatchToProps(dispatch) return ...bindActionCreators( increment, decrement ), dispatch ;
以上是关于如何使用带 Redux 的连接从 this.props 获得简单的调度?的主要内容,如果未能解决你的问题,请参考以下文章
Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件
当输入字段已经使用 useState() 映射时,如何使用 useSelector() 连接 redux 存储