如何将动作传递给Redux中的组件 [英] How to pass actions down to the components in redux

查看:68
本文介绍了如何将动作传递给Redux中的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的组件中触发一个动作.这是一个演示组件,不需要Redux感知.路由器的实现是使用react-router-redux完成的.

I want to fire an action down in my component. This is a presentation component and need not be redux aware. Router implementation is done using react-router-redux.

main.js:

let store = createStore(rootReducer)

const history = syncHistoryWithStore(hashHistory, store)

class RenderClass extends Component {
  render() {
    return (
        <Provider store={store}>
            <Router history={history}>
                <Route path="/" component={MainLayout}>
                    <Route name="employees" path="/employees" url="http://localhost:8080/" component={EmployeeTable}></Route>
                    <Route name="personalInformation" path="/personalInformation/:employeeId" url={URI} component={PersonalInformation} />
                    .....
                </Route>
            <Router>
        </Provider>
        );
    }
}   

App.jsx:

import * as Actions from './action-creator';
const MainLayout = React.createClass({
                render: function() {

                    const { dispatch, list } = this.props;
                    let actions = bindActionCreators(Actions, dispatch);
                    console.log(actions);

                    return (
                        <div className="wrapper">
                            <Header actions={actions} list={list} params={this.props.params} />

                    {React.cloneElement(this.props.children, this.props)}
                        </div>
                    )
                }
            }); 

function select(state) {
   return {
      list: state.listingReducer
   }
}
export default connect(select)(MainLayout);

header.js:

header.js:

define(
    [
        'react',
        'jquery',
        'appMin'
    ],
    function (React, $) {
        var Link = require('reactRouter').Link;
        var Header = React.createClass({
            handleClick: function () {
                //Action called here
                this.props.actions.listEmployees();
            },      
            render: function () {
                return (
                    <ul className="sidebar-menu">
                        <li>
                            <Link to={'/employees'} onClick={this.handleClick}><i className="fa fa-home"></i>Employees</Link> 
                        </li> 
                    </ul>
                );
            }
        });
        return Header;
    }
)

employee.js:

employee.js:

define(
    [
        'react',
        'jquery',
        'appMin'
    ],
    function (React, $) {
        var EmployeeTable = React.createClass({

            render: function () {
                if (this.props.list != undefined) {
                    var listItems = this.props.list.map(function (listItem) {
                        return (
                            <tr key={listItem.id}>
                                <td> {listItem.name}</td>
                <td><Link to={'/personalInformation/' + employee.id} onClick={this.props.actions.displayPersonalInformation(employee.id)}>Personal Information</Link></td>
                                ......
                            </tr>
                        );
                    }, this);   
                    })
                }
                return (
                    <table>
                        <tbody>
                            {listItems}
                        </tbody>                    
                    </table>
                );
            }
        })  
    }
)

action-creator.js:

action-creator.js:

export function listEmployees() {
    return {
      type: types.LIST_EMPLOYEES
   };
}

export function displayPersonalInformation() {
        return {
          type: types.DISPLAY_PERSONAL_INFORMATION
       };
    }

reducer.js:
function addEmployee(state, action) {

   switch (action.type) {

      case types.LIST_EMPLOYEES:
         return {"id":"1", "name":"Stackoverflow"}

      default:
        return state
   }
}

function listingReducer(state = [], action) {
    switch (action.type) {

        case types.LIST_EMPLOYEES:
            return [
                ...state, 
                addEmployee(undefined, action)
            ]

        case types.DISPLAY_PERSONAL_INFORMATION:
                return // Gets personal Information

        default:
            return state;
    }
}


const rootReducer = combineReducers({
   listingReducer
})

export default rootReducer

由于我没有将道具绑定到道具,因此道具将不包含任何动作.我尝试在 App.js 中编写mapStateToProps和mapDispatchToProps,如下所示:

The props will not contain actions since I have not tied it to props. I tried writing mapStateToProps and mapDispatchToProps in App.js as shown below:

function mapStateToProps(state) {
   return {
        list: state.list
    }
}

function mapDispatchToProps(dispatch) {
   return { actions: bindActionCreators({ actionCreators }, dispatch) }
}

导出默认连接(mapStateToProps,mapDispatchToProps)(MainLayout) 我正在调度不是函数错误.错误语句实际上听起来像是stackoverflow中的重复问题,但是我也想知道为什么我使用mapDispatchToProps的目的也是正确的.预先感谢.

export default connect(mapStateToProps, mapDispatchToProps)(MainLayout) I'm getting dispatch is not a function error. The error statement actually sounds like a duplicate question in stackoverflow, but I would also like to know the purpose why I'm using mapDispatchToProps is also right. Thanks in advance.

推荐答案

因此,据我了解,您正在使用export default connect(mapStateToProps, mapDispatchToProps)(MainLayout)并尝试在MainLayout中调用dispatch.

So from what I understand you are using export default connect(mapStateToProps, mapDispatchToProps)(MainLayout) and trying to call dispatch in MainLayout.

因此,如果您看到react-redux文档,则可以通过以下方式调用connect:-

So from the react-redux documentation if you see you can call connect in following ways:-

  • connect()(//Component)->调度将作为道具传递
  • connect(mapStateToProps)(//Component)->调度将作为道具传递
  • connect(mapStateToProps,mapDispatchToProps)(//Component)-> 调度不会作为道具传递给您的组件
  • connect()(//Component) --> dispatch would be passed as props
  • connect(mapStateToProps)(//Component) --> dispatch would be passed as props
  • connect(mapStateToProps,mapDispatchToProps)(//Component) --> dispatch would not be passed as props to your component

在方案3中,行为是这种方式,因为mapDispatchToProps已经可以使用调度功能.因此,您可以将函数绑定到mapDispatchToProps中进行分派,然后将此函数传递给组件.

In scenario 3 the behavior is this way because mapDispatchToProps already has access to dispatch function. So you can bind your function to dispatch in mapDispatchToProps and then pass on this function to your component.

示例

您要分派的函数是dispatchMe()dispatchMe2(),它们调用一个称为dispatchAction的动作.因此,您的mapDispatchToProps类似于:-

The function you want to dispatch are dispatchMe() and dispatchMe2() which calls an action called dispatchAction. So your mapDispatchToProps would be something like :-

function mapDispatchToProps(dispatch){
  return {
     dispatchMe : () => {
       dispatch(dispatchAction()) 
    },
    dispatchMe2 : () => {
      dispatch(dispatchAction2())
    }
  }
}

现在您可以在组件中传递dispatchMe并在需要时调用它.

Now in your component you can pass dispatchMe and call it when required.

您可以在此处阅读有关更多信息

You can read here for more info on this

这篇关于如何将动作传递给Redux中的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆