首页 文章

如何使用connect w / Redux从this.props获得简单的调度?

提问于
浏览
91

我有一个简单的React组件,我连接起来(映射一个简单的数组/状态) . 为了避免引用商店的上下文,我想要一种直接从道具中“调度”的方法 . 我见过其他人使用这种方法,但由于某种原因无法访问这个:)

以下是我目前正在使用的每个npm依赖项的版本

"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"

这是组件w / connect方法

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;
};

如果你需要看看我的路由器如何配置w / redux

const createStoreWithMiddleware = applyMiddleware(
      thunk
)(createStore);

const store = createStoreWithMiddleware(reducers);

var Route = (
  <Provider store={store}>
    <Router history={createBrowserHistory()}>
      {Routes}
    </Router>
  </Provider>
);

update

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

[mapDispatchToProps]

3 回答

  • 1

    您通常可以根据自己的喜好混合搭配 .

    如果这是您想要的,您可以将 dispatch 作为道具传递:

    export default connect(mapStateToProps, (dispatch) => ({
        ...bindActionCreators({fetchUsers}, dispatch), dispatch
    }))(Users);
    

    我不确定如何使用 fetchUsers (作为异步函数?),但是你通常会使用像 bindActionCreators 之类的东西来自动绑定调度,然后你就不必担心在连接的组件中直接使用 dispatch 了 .

    使用 dispatch 目录排序将dumb,无状态组件与redux相结合 . 这可以减少便携性 .

  • 256

    默认 mapDispatchToProps 只是 dispatch => ({ dispatch }) .
    因此,如果您未指定 connect() 的第二个参数,则会在组件中将 dispatch 作为prop进行注入 .

    如果将自定义函数传递给 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 .

  • 4

    虽然您可以将 dispatch 作为 dispatchToProps 的一部分向下传递,但我建议您不要直接从组件中访问 storedispatch . 看来你可以通过在连接的第二个参数 dispatchToProps 中传递绑定的动作创建者来获得更好的服务

    查看我在这里发布的一个示例https://stackoverflow.com/a/34455431/2644281如何传递"already bound action creator",这样您的组件就不需要直接了解或依赖于存储/调度 .

    很抱歉要简短 . 我会更新更多信息 .

相关问题