使用复选框将多个项目添加到阵列-redux react

时间:2019-07-16 04:38:21

标签: javascript reactjs redux

在我的应用程序中有一个项目列表。在每个项目中都有一个复选框。如果我检查了多个项目并单击添加按钮,则从该列表项目中添加了“添加已检查”按钮。那些选中的项目将添加到另一个列表中。我已经创建了动作和减速器功能,因为它工作正常。但是,它仅添加了最后检查的单个项目

我试图将所有选中的项目存储在一个基于mruCode(id)的数组中,然后使用onClick按钮函数将整个数组调用到另一个数组中。但是,它只发送单个项目。

动作代码:(到目前为止,我已经尝试过如何将checkboxstate动作确定为添加)

export const checkboxState = mruCode =>({
  type: GET_CHECKBOX,
  payload : mruCode
});

export const checkedLocation = () =>({
  type: GET_CHECKED_LOCATION
});

减速器功能(加法运算)

case 'GET_CHECKBOX':
        let newState1 = Object.assign({},state)
        let newList = newState1.location.filter((obj)=>obj.mruCode===action.payload)
        return Object.assign({},newState1,{
            isChecked: newList
        });

        case 'GET_CHECKED_LOCATION':
          return{
              ...state,
              conLocations:[...state.isChecked]
          }    

组件代码:

export class NewLocationPanel extends React.Component{
    constructor(props){
        super(props);
        this.state={
               open:false,
               configuredList:[]
        };
       this.configLocation = this.configLocation.bind(this);
        this.togglePanel = this.togglePanel.bind(this);
        this.handleClick = this.handleClick.bind(this);
        this.allLocations = this.allLocations.bind(this);
        this.clearall = this.clearall.bind(this);
        this.getLocationData = this.getLocationData.bind(this);
        this.handleRemove = this.handleRemove.bind(this);
        this.removeConfigLocation = this.removeConfigLocation.bind(this);
        this.removeLocationAll = this.removeLocationAll.bind(this);
        this.handleChecklocation = this.handleChecklocation.bind(this);
        this.handleCheckedAdded = this.handleCheckedAdded.bind(this);
    }

    // there is other code

    handleChecklocation(mruCode){
        this.props.checkboxState(mruCode)
    }

    handleCheckedAdded(){
        this.props.checkedLocation()
    }

    componentDidMount() {
        this.props.loadData();
        if(this.props.locationData !=null && this.props.locationData!= undefined){
            this.configLocation(this.props.locationData);
        }
      }

    componentDidUpdate(prevProps,prevState){
        if (prevProps.locationData != this.props.locationData){ 
            this.configLocation(this.props.locationData);
        }
    }

   //there are other non-related function

    render(){
        //const{configuredList} = this.state;
        const _labels = store.getLabels();
        let collapsedToggle = this.props.open ? 'collapsed' : ''
        return(
            <div className="panel panel-default">
            <div className="panel-heading" onClick={(e)=>this.togglePanel(e)}>
              <div className="row">
              <div className="col-xs-12 col-sm-8 col-md-6 col-lg-6 panelHeadingLabel">
                     <span>{this.props.title}</span>
                     </div>
                        <div className="pull-right">
                        <span className="defaultHeaderTextColor">{this.state.configuredList.map((loc,index)=><span key={index}>{loc.mruCode} - {_labels[loc.division]} - {loc.country}{index < this.state.configuredList.length-1 ?',\u00A0' : ''}</span>)}
                           <span onClick={(e)=>this.togglePanel(e)} className={this.state.open ? "collapse-chevronn" : "collapse-chevron"} aria-hidden="true"></span>
                   </span>
                    </div>
                </div>
           </div>
              {this.state.open?(
                        <div className="panel-body">
                             <div className="row grid-divider">
                             <div className="col-sm-6">
                             <div className="col-padding"><div className="pos-div"><h3>Locations List</h3><button className="submitSmallBtn1"  onClick={()=>this.handleCheckedAdded()}>Add Checked</button><button style={{ display: this.props.location.length === this.props.conLocations.length ? "none" : "block" }} className="allLargeBtn" onClick={()=>{this.allLocations()}}>Add all locations</button></div><hr/>
                             {this.props.location.map((item,index)=>(
                             <div key={index}><div><input type="checkbox" onClick={()=>this.handleChecklocation(item.mruCode)}/><label></label><b>{item.mruCode} - {_labels[item.division]} - {item.country}</b>{!this.props.conLocations.find(item2 => item.mruCode === item2.mruCode)&&(<div className="pull-right jd"><button style={{ display: this.state.configuredList.find(item3=> item.mruCode===item3.mruCode) ? "none" : "block" }} className="call-to-action" onClick={()=>{this.handleClick(item.mruCode)}}>Add Location</button></div>)}<hr/></div></div>))}
                            </div>
                             </div> 
                                  </div> 
                    </div>):null}
            </div>

        );
    }
}

const mapStateToProps = state =>{
    return{
        location:state.locationRed.location,
        conLocations:state.locationRed.conLocations,
        isChecked:state.locationRed.isChecked
    };
};

const mapDispatchToProps = (dispatch) => {
    return{
        loadData:()=>{dispatch(loadData())},
        addLocation:(mruCode)=>{dispatch(addLocation(mruCode))},
        addAllLocation:() =>{dispatch(addAllLocation())},
        removeLocation: (mruCode)=>{dispatch(removeLocation(mruCode))},
        removeAllLocation: () =>{dispatch(removeAllLocation())},
        checkboxState: (mruCode) =>{dispatch(checkboxState(mruCode))},
        checkedLocation:() =>{dispatch(checkedLocation())}

    }
}


export default connect(mapStateToProps,mapDispatchToProps,null,{withRef:true})(NewLocationPanel);

在组件中,有一个“已选中添加”按钮,通过该按钮将基于所选项目进行添加操作。如果我选择两个项目,则只有第二个项目添加到另一个列表中。

初始位置列表如下: [{mruCode:“ 7300”,国家/地区:“ AUSTRALIA”,州:“ Queensland”,部门:“ Engineering”,...},...]

2 个答案:

答案 0 :(得分:1)

我了解您在列表中有多个复选框。整个选择完成后,单击“添加已选中”按钮,您要存储所选项目。

这可以通过其他方式完成,我们可以在组件状态下存储每个复选框的已选中状态,而不是在复选框的每个选中/取消选中时分派动作。

您可以使用event.target.checked(更改句柄)方法跟踪选定的复选框,并将其存储在状态中。

在单击“添加已检查”按钮时,调度操作并将整个选定列表发送到减速器。希望这会有所帮助!

答案 1 :(得分:0)

经过多次试验,我找到了解决方案。我创建了将选中的项目过滤后存储到列表中的操作,然后通过调度按钮操作事件直接将其发送到列表中。 动作代码:

 export const checkboxState = mruCode =>({

类型:GET_CHECKBOX,   有效负载:mruCode });

export constcheckedLocation =()=>({   类型:GET_CHECKED_LOCATION });

减速器功能

case 'GET_CHECKBOX':
    let newList = state.location.filter(obj=>obj.mruCode===action.payload)
    let addedItems = state.isChecked.concat(newList)
    return{
         ...state,
         isChecked:addedItems
    }
    case 'GET_CHECKED_LOCATION':
      return{
          ...state,
          conLocations:[...state.isChecked]
      }    

现在可以正常工作了。问题出在我以前的动作上。