2017-08-15 105 views
0

我有一个组件UsersList,我想用两个不同的缩减器重用 - 一个用于列出普通用户(state.users.x),另一个用于列出管理员(状态。 adminusers.x)。显示在两种情况下都是相同的,但是状态位于不同的地方并且应用了不同的api操作(具有不同业务规则的不同端点)。Redux:为组件使用不同的缩减器

如何编写我的组件,以便它可以使用任一个reducer?

+0

Reducer本身是状态容器,它不负责API调用。如果你想访问不同的reducer,你可以在'mapStateToProps'中订阅它们。但是为了调用不同的API端点,您需要访问不同的操作并在'componentDidMount'中有条件语句来调用它们。 –

回答

3
  1. 正常写入UsersList组件,但不要将它连接到redux。

例如:

import React, { Component } from 'react'; 
import { Table } from 'react-bootstrap'; 
import UserInviteRow from 'jsx/components/Lib/Users/UserInviteRow'; 

export class UsersList extends Component { 

    render() { 
     const { inviteUserToOrg } = this.props; 

     return (
      <Table bordered hover> 
       <thead> 
        <tr> 
         <th className="width-200">First Name</th> 
         <th className="width-250">Last Name</th> 
         <th>Email</th> 
         <th className="width-150">Last Login</th> 
         <th className="width-100">&nbsp;</th> 
        </tr> 
       </thead> 
       <tbody> 
        <UserInviteRow invitefxn={ inviteUserToOrg }/> 
        { this.renderRows() } 
       </tbody> 
      </Table> 
     ); 
    } 

    renderRows() { 
     const { usersList } = this.props; 
     if(! usersList.length) { 
      return (
       <tr> 
        <td colSpan="5"> 
         <em>No users exist for this non-profit</em> 
        </td> 
       </tr> 
      ); 
     } 

     return usersList.map((user) => { 
      return (
       <tr key={user.key}> 
        <td>{user.firstName}</td> 
        <td>{user.lastName}</td> 
        <td>{user.correspondenceEmailAddress}</td> 
        <td>{ (user.lastSeen) ? formatTime(user.lastSeen) : '' }</td> 
        <td className="text-center"> 
         { this.renderRemoveButton(user) } 
        </td> 
       </tr> 
      ); 
     }); 
    } 

    renderRemoveButton(user) { 
     const { currentUser } = this.props; 
     if(currentUser.key === user.key) { 
      // users cannot remove themselves 
      return null; 
     } 

     return (
      <a className="text-danger" onClick={() => { this.removeUser(user) } }> 
       <em className="fa fa-times" /> 
      </a> 
     ); 
    } 

    removeUser(user) { 
     this.props.removeUserFromOrg(user.key); 
    } 
} 

export default UsersList; 
  • 确保两个您减速器实现你用行动功能,在这种情况下inviteUserToOrgremoveUserFromOrg

  • 创建连接到每个减速

  • 例如新容器组件:

    import { connect } from 'react-redux'; 
    import { 
        inviteUserToOrg, 
        removeUserFromOrg 
    } as actions from 'jsx/redux/modules/nonadminUsers'; 
    import UsersList from 'jsx/components/Lib/Users/UsersList'; 
    
    var NonadminUserList = connect(
        state => { 
        return { 
         usersList: state.users.usersList, 
        }; 
        }, 
        actions 
    )(UsersList); 
    
    export default NonadminUserList; 
    

    import { connect } from 'react-redux'; 
    import { 
        inviteUserToOrg, 
        removeUserFromOrg 
    } as actions from 'jsx/redux/modules/adminUsers'; 
    import UsersList from 'jsx/components/Lib/Users/UsersList'; 
    
    var AdminUserList = connect(
        state => { 
         return { 
          usersList: state.adminusers.usersList, 
         }; 
        }, 
        actions 
    )(UsersList); 
    
    export default AdminUserList; 
    

    现在改变为您的演示组件,UsersList,将影响容器组件和每个容器组件都可以引用它自己的减速器泰特和行动。

    +0

    作为一个侧面说明,在花费更多时间与redux后,我得出的结论是,虽然这在技术上有效,但这是一个相当丑陋的修复;作为一般规则,这些问题可以通过优先将数据作为道具传递给组件并仅连接最高级别的视图组件来避免。 – perilandmishap