本文介绍了如何使用带有 Redux 的连接从 this.props 获得简单的调度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 React 组件可以连接(映射一个简单的数组/状态).为了避免引用 store 的上下文,我想要一种直接从 props 获取调度"的方法.我见过其他人使用这种方法,但由于某种原因无法访问它:)

这是我当前使用的每个 npm 依赖项的版本

"react": "0.14.3","react-redux": "^4.0.0",反应路由器":1.0.1","redux": "^3.0.4",redux-thunk":^1.0.2"

这是带有连接方法的组件

class 用户扩展 React.Component {使成为() {const { 人 } = this.props;返回 (<div><div>{this.props.children}</div><button onClick={() =>{ this.props.dispatch({type: ActionTypes.ADD_USER, id: 4});}}>添加用户</button>

);}};函数 mapStateToProps(state) {返回 { 人:state.people };}导出默认连接(mapStateToProps,{获取用户})(用户);

如果您需要查看减速器(没什么令人兴奋的,但在这里)

const initialState = {人们: []};导出默认功能(状态=初始状态,动作){if (action.type === ActionTypes.ADD_USER) {让 newPeople = state.people.concat([{id: action.id, name: 'wat'}]);返回{人:新人};}返回状态;};

如果您需要查看我的路由器是如何使用 redux 配置的

const createStoreWithMiddleware = applyMiddleware(重击)(创建商店);const store = createStoreWithMiddleware(reducers);无功路线=(<提供者商店={商店}><路由器历史={createBrowserHistory()}>{路线}</路由器></提供者>);

更新

看起来如果我在连接中省略我自己的调度(当前上面我正在显示 fetchUsers),我将获得免费调度(只是不确定这是否是带有异步操作的设置通常会如何工作).人们是混搭还是全有或全无?

[mapDispatchToProps]

解决方案

默认情况下 mapDispatchToProps 只是 dispatch =>({ dispatch }).
因此,如果您没有为 connect() 指定第二个参数,您将在组件中将 dispatch 作为 prop 注入.

如果您将自定义函数传递给 mapDispatchToProps,则您可以对该函数执行任何操作.
几个例子:

//注入 onClick函数 mapDispatchToProps(dispatch) {返回 {onClick: () =>调度(增量())};}//注入 onClick *and* dispatch函数 mapDispatchToProps(dispatch) {返回 {派遣,onClick: () =>调度(增量())};}

为了节省你的一些输入,Redux 提供了 bindActionCreators() 来让你改变这个:

//注入 onPlusClick, onMinusClick函数 mapDispatchToProps(dispatch) {返回 {onPlusClick: () =>调度(增量()),onMinusClick: () =>调度(递减())};}

进入这个:

import { bindActionCreators } from 'redux';//注入 onPlusClick, onMinusClick函数 mapDispatchToProps(dispatch) {返回 bindActionCreators({onPlusClick:增量,onMinusClick:递减}, 派遣);}

当道具名称与动作创建者名称匹配时甚至更短:

//注入增量和减量函数 mapDispatchToProps(dispatch) {return bindActionCreators({ increment, decrement }, dispatch);}

如果你愿意,你绝对可以手动添加dispatch:

//注入增量、减量和调度自身函数 mapDispatchToProps(dispatch) {返回 {...bindActionCreators({ increment, decrement }),//es7 扩展语法派遣};}

没有关于您是否应该这样做的官方建议.connect() 通常用作 Redux-aware 和 Redux-unaware 组件之间的边界.这就是为什么我们通常认为同时注入 绑定动作创建器和 dispatch 是没有意义的.但是,如果您觉得需要这样做,请随时这样做.

最后,您现在使用的模式是一个比调用 bindActionCreators 还要短的快捷方式.当您所做的只是返回 bindActionCreators 时,您可以省略调用,而不是这样做:

//注入增量和减量函数 mapDispatchToProps(dispatch) {return bindActionCreators({ increment, decrement }, dispatch);}导出默认连接(mapStateToProps,mapDispatchToProps)(应用程序);

可以这样写

导出默认连接(mapStateToProps,{ increment, decrement }//注入增量和减量)(应用程序);

然而,当您想要更自定义的东西时,例如传递 dispatch 以及.

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 :)

Here are the versions of each npm dependency I'm using currently

"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

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?

[mapDispatchToProps]

解决方案

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.

If you pass a custom function to mapDispatchToProps, you can do anything with the function.
A few examples:

// 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:

// 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:

// 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 both bound action creators and dispatch. But if you feel like you need to do this, feel free to.

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:

// 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.

这篇关于如何使用带有 Redux 的连接从 this.props 获得简单的调度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 10:27