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

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

问题描述

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

main.js:

let store = createStore(rootReducer)const history = syncHistoryWithStore(hashHistory, store)类 RenderClass 扩展组件 {使成为() {返回 (<提供者商店={商店}><路由器历史={历史}><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}/>.....</路线><路由器></提供者>);}}

App.jsx:

import * as Actions from './action-creator';const MainLayout = React.createClass({渲染:函数(){const { dispatch, list } = this.props;让动作 = bindActionCreators(Actions, dispatch);控制台日志(操作);返回 (<div className="包装器"><Header actions={actions} list={list} params={this.props.params}/>{React.cloneElement(this.props.children, this.props)}

)}});功能选择(状态){返回 {列表:state.listingReducer}}导出默认连接(选择)(MainLayout);

header.js:

define(['反应','jquery','appMin'],功能(反应,$){var Link = require('reactRouter').Link;var Header = React.createClass({句柄点击:函数(){//此处调用的动作this.props.actions.listEmployees();},渲染:函数(){返回 (<ul className="sidebar-menu"><li><Link to={'/employees'} onClick={this.handleClick}><i className="fa fa-home"></i>Employees</Link>);}});返回标题;})

employee.js:

define(['反应','jquery','appMin'],功能(反应,$){var EmployeeTable = React.createClass({渲染:函数(){如果 (this.props.list != undefined) {var listItems = this.props.list.map(function (listItem) {返回 (<td>{listItem.name}</td><td><Link to={'/personalInformation/' + employee.id} onClick={this.props.actions.displayPersonalInformation(employee.id)}>个人信息</Link></td>......</tr>);}, 这);})}返回 (<表格>{列表项}</tbody>);}})})

action-creator.js:

导出函数 listEmployees() {返回 {类型:types.LIST_EMPLOYEES};}导出函数 displayPersonalInformation() {返回 {类型:types.DISPLAY_PERSONAL_INFORMATION};}减速器.js:函数添加员工(状态,动作){开关(动作.类型){案例类型.LIST_EMPLOYEES:返回 {"id":"1", "name":"Stackoverflow"}默认:返回状态}}函数listingReducer(state = [], action) {开关(动作.类型){案例类型.LIST_EMPLOYEES:返回 [...状态,addEmployee(未定义,动作)]案例类型.DISPLAY_PERSONAL_INFORMATION:return//获取个人信息默认:返回状态;}}const rootReducer = combineReducers({上市减速机})导出默认 rootReducer

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

function mapStateToProps(state) {返回 {列表:state.list}}函数 mapDispatchToProps(dispatch) {返回 { 动作:bindActionCreators({ actionCreators }, dispatch) }}

导出默认连接(mapStateToProps, mapDispatchToProps)(MainLayout)我得到 dispatch 不是函数错误.错误语句实际上听起来像是 stackoverflow 中的重复问题,但我也想知道我使用 mapDispatchToProps 的目的也是正确的.提前致谢.

解决方案

所以据我所知你正在使用 export default connect(mapStateToProps, mapDispatchToProps)(MainLayout) 并试图调用 MainLayout 中的 dispatch.

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

  • connect()(//Component) --> dispatch 将作为 props 传递
  • connect(mapStateToProps)(//Component) --> dispatch 将作为 props 传递
  • connect(mapStateToProps,mapDispatchToProps)(//Component) --> dispatch 不会作为道具传递给您的组件

在场景 3 中,行为是这样的,因为 mapDispatchToProps 已经可以访问调度函数.因此,您可以在 mapDispatchToProps 中绑定您的函数以进行调度,然后将此函数传递给您的组件.

示例

您要调度的函数是dispatchMe()dispatchMe2(),它们调用一个名为dispatchAction 的动作.所以你的 mapDispatchToProps 将类似于 :-

function mapDispatchToProps(dispatch){返回 {dispatchMe : () =>{调度(调度动作())},dispatchMe2 : () =>{分派(dispatchAction2())}}}

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

您可以阅读此处了解更多信息

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:

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:

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:

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

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

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.

解决方案

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

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

  • 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

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.

Example

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())
    }
  }
}

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天全站免登陆