Javascript 如何使用带有 Redux 的连接从 this.props 获得简单的调度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34458261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get simple dispatch from this.props using connect w/ Redux?
提问by Toran Billups
I've got a simple React component that I connect up (mapping a simple array/state over). To keep from referencing the context for store I'd like a way to get "dispatch" directly from props. I've seen others using this approach but don't have access to this for some reason :)
我有一个简单的 React 组件可以连接(映射一个简单的数组/状态)。为了避免引用 store 的上下文,我想要一种直接从 props 获取“调度”的方法。我见过其他人使用这种方法,但由于某种原因无法访问它:)
Here are the versions of each npm dependency I'm using currently
这是我当前使用的每个 npm 依赖项的版本
"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"
Here is the component w/ connect method
这是带有连接方法的组件
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);
If you need to see the reducer (nothing exciting but here it is)
如果您需要查看减速器(没什么令人兴奋的,但在这里)
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;
};
If you need to see how my router is configured w/ redux
如果您需要查看我的路由器是如何使用 redux 配置的
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
const store = createStoreWithMiddleware(reducers);
var Route = (
<Provider store={store}>
<Router history={createBrowserHistory()}>
{Routes}
</Router>
</Provider>
);
update
更新
looks like if I omit my own dispatch in the connect (currently above I'm showing fetchUsers), I'd get dispatch free (just not sure if this is how a setup w/ async actions would work usually). Do people mix and match or is it all or nothing?
看起来如果我在连接中省略我自己的调度(当前上面我正在显示 fetchUsers),我将获得免费调度(只是不确定这是否是具有异步操作的设置通常会如何工作)。人们是混搭还是全有或全无?
[mapDispatchToProps]
[mapDispatchToProps]
回答by Dan Abramov
By default mapDispatchToProps
is just dispatch => ({ dispatch })
.
So if you don't specify the second argument to connect()
, you'll get dispatch
injected as a prop in your component.
默认情况下mapDispatchToProps
只是dispatch => ({ dispatch })
.
因此,如果您没有为 指定第二个参数connect()
,您将dispatch
作为组件中的道具被注入。
If you pass a custom function to mapDispatchToProps
, you can do anything with the function.
A few examples:
如果将自定义函数传递给mapDispatchToProps
,则可以对该函数执行任何操作。
几个例子:
// inject onClick
function mapDispatchToProps(dispatch) {
return {
onClick: () => dispatch(increment())
};
}
// inject onClick *and* dispatch
function mapDispatchToProps(dispatch) {
return {
dispatch,
onClick: () => dispatch(increment())
};
}
To save you some typing Redux provides bindActionCreators()
that lets you turn this:
为了节省您的一些输入,Redux 提供bindActionCreators()
了可以让您转的:
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
return {
onPlusClick: () => dispatch(increment()),
onMinusClick: () => dispatch(decrement())
};
}
into this:
进入这个:
import { bindActionCreators } from 'redux';
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
return bindActionCreators({
onPlusClick: increment,
onMinusClick: decrement
}, dispatch);
}
or even shorter when prop names match action creator names:
当道具名称与动作创建者名称匹配时,甚至更短:
// injects increment and decrement
function mapDispatchToProps(dispatch) {
return bindActionCreators({ increment, decrement }, dispatch);
}
If you'd like you can definitely add dispatch
there by hand:
如果您愿意,您绝对可以dispatch
手动添加:
// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ increment, decrement }), // es7 spread syntax
dispatch
};
}
There's no official advise on whether you should do this or not. connect()
usually serves as the boundary between Redux-aware and Redux-unaware components. This is why we usually feel that it doesn't make sense to inject bothbound action creators and dispatch
. But if you feel like you need to do this, feel free to.
没有关于您是否应该这样做的官方建议。connect()
通常用作 Redux-aware 和 Redux-unaware 组件之间的边界。这就是为什么我们通常觉得它没有意义注入两个有时限的行动创造者和dispatch
。但如果你觉得你需要这样做,请随意。
Finally, the pattern you are using right now is a shortcut that's even shorter than calling bindActionCreators
. When all you do is return bindActionCreators
, you can omit the call so instead of doing this:
最后,您现在使用的模式是一个比调用bindActionCreators
. 当您所做的只是 return 时bindActionCreators
,您可以省略调用而不是这样做:
// injects increment and decrement
function mapDispatchToProps(dispatch) {
return bindActionCreators({ increment, decrement }, dispatch);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
can be written as this
可以写成这样
export default connect(
mapStateToProps,
{ increment, decrement } // injects increment and decrement
)(App);
However you'll have to give up that nice short syntax whenever you want something more custom, like passing dispatch
as well.
然而,当你想要更自定义的东西时,你就必须放弃那种漂亮的简短语法,比如传递dispatch
。
回答by Davin Tryon
You can usually mix and match based on what you'd like.
您通常可以根据自己的喜好混合搭配。
You canpass dispatch
on as a prop if that is what you want:
如果这是你想要的,你可以dispatch
作为道具传递:
export default connect(mapStateToProps, (dispatch) => ({
...bindActionCreators({fetchUsers}, dispatch), dispatch
}))(Users);
I'm not sure how fetchUsers
is used (as an async function?), but you would usually use something like bindActionCreators
to auto-binddispatch and then you would not have to worry about using dispatch
directly in connected components.
我不知道如何fetchUsers
使用(如异步功能?),但你通常会使用类似bindActionCreators
来自动绑定调度,然后你就不必担心使用dispatch
直接连接的部件。
Using dispatch
directory sort of couples the dumb, stateless component with redux. Which can make it less portable.
使用dispatch
目录排序将愚蠢的、无状态的组件与 redux 结合起来。这可以使它不那么便携。
回答by Erik Aybar
While you could pass dispatch
down as part of dispatchToProps
, I would recommend avoiding accessing the store
or dispatch
directly from within your components. It seems like you would be better served by passing in a bound action creator in connect's 2nd argument dispatchToProps
虽然您可以dispatch
作为 的一部分传递下去dispatchToProps
,但我建议避免直接从您的组件内部访问store
或dispatch
。似乎通过在连接的第二个参数中传递绑定动作创建者会更好地为您服务dispatchToProps
See an example I posted here https://stackoverflow.com/a/34455431/2644281of how to pass down an "already bound action creator" this way your components don't need to directly know about or depend on the store/dispatch.
请参阅我在此处发布的示例https://stackoverflow.com/a/34455431/2644281,了解如何通过这种方式传递“已经绑定的动作创建者”,您的组件无需直接了解或依赖于商店/分派.
Sorry to be brief. I'll update w/ more info.
抱歉,要简短。我会更新更多信息。