简体   繁体   中英

Using 2 dropdowns in React. Cannot read property 'map' of undefined

I'm having an issue with 2 dropdowns. I'm getting the following error: TypeError: Cannot read property 'map' of undefined .

Both dropdowns should work at the same time depending if the user wants to select a value from one of them or wants to select values from both dropdowns.

This is how I have implemented my 2 Dropdowns and how they should work. If I click the button I will get the error: 在此处输入图像描述

dropdown.js

import * as actionTypes from '../actions';

const initialState = {
    selection: 'Ambos',
    dropdownValues: ['Chatbot', 'Agente'],

    selectionME: 'Todos',
    dropdownValuesME: ['Messenger', 'Web', 'WhatsApp']

};
//
const reducer = ( state = initialState, action ) => {
    if (typeof state === 'undefined') {
        return initialState
    }

    switch ( action.type ) {
        case actionTypes.UPDATE_SELECTION:
        {
            return {
                
                ...state,
                selection: action.dataSelected,
                dropdownValues: action.dropdownValues,

                selectionME: action.dataSelectedME,
                dropdownValuesME: action.dropdownValuesME
            }
        }
        default: {
         //statements;
         
         break;
        }
    }
    return state;
};


export default reducer;

DropdownSelect.js

import React, { Component } from 'react';
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
import {connect} from 'react-redux';
import * as actionTypes from '../../store/actions'

class DropdownSelect extends Component {

  constructor(props)
{
  super(props);
  console.log(props)
  this.state = {
    dropdownOpen: false,
    solved: this.props.selectData,
    dropdownValues: this.props.dropdownValues,

    dropdownOpenME: false,
    solvedME: this.props.selectDataME,
    dropdownValuesME: this.props.dropdownValuesME,
  }
}

componentDidMount() {
  if(this.props.onRef)
  this.props.onRef(this);

}

toggleDropdown = () => {
  this.setState({
    dropdownOpen: !this.state.dropdownOpen,
  });
}

toggleDropdown2 = () => {
  this.setState({
    dropdownOpenME: !this.state.dropdownOpenME,
  });
}

changeDropdownValue = async (event) => {
    const currentSolved = this.state.solved
    let newdropdownValues = this.state.dropdownValues.concat(currentSolved)
    newdropdownValues = newdropdownValues.filter(item => item !== event.target.innerText)

    await this.setState({
        dropdownOpen: !this.state.dropdownOpen,
        solved: event.target.innerText,
        dropdownValues: newdropdownValues,

    }, () => {
       this.props.onUpdate(this.state.solved, this.state.dropdownValues);
    });
}
changeDropdownValueME = async (event) => {
  const currentSolvedME = this.state.solvedME
  let newdropdownValuesME = this.state.dropdownValuesME.concat(currentSolvedME)
  newdropdownValuesME = newdropdownValuesME.filter(item2 => item2 !== event.target.innerText)

  await this.setState({
      dropdownOpenME: !this.state.dropdownOpenME,
      solvedME: event.target.innerText,
      dropdownValuesME: newdropdownValuesME

  }, () => {
     this.props.onUpdate(this.state.solvedME, this.state.dropdownValuesME);
  });
}

  render() {
    return (
    <>                              
      <ButtonDropdown isOpen={this.state.dropdownOpen} toggle={this.toggleDropdown}>
        <DropdownToggle caret>
        {this.state.solved}
        </DropdownToggle>
        <DropdownMenu>
          {this.state.dropdownValues.map(e => {return <DropdownItem key={e} onClick={this.changeDropdownValue}>{e}</DropdownItem>})}
        </DropdownMenu>
      </ButtonDropdown>
      
      <p className="text-uppercase text-left font-weight-bold -label">Tipo de atención</p>
      <ButtonDropdown isOpen={this.state.dropdownOpenME} toggle={this.toggleDropdown2}>
        <DropdownToggle caret>
        {this.state.solvedME}
        </DropdownToggle>
        <DropdownMenu>
          {this.state.dropdownValuesME.map(e => {return <DropdownItem key={e} onClick={this.changeDropdownValueME}>{e}</DropdownItem>})}
        </DropdownMenu>
      </ButtonDropdown>

      </>
    );
  }
}

const mapStateToProps = state => ({
  //selectData: state.dropDownReducer.selection || [],
  //dropdownValues: state.dropDownReducer.dropdownValues || ['Ambos', 'Chatbot', 'Agente'],
  selectData: state.dropDownReducer.selection,
  dropdownValues: state.dropDownReducer.dropdownValues,

  selectDataME: state.dropDownReducer.selectionME,
  dropdownValuesME: state.dropDownReducer.dropdownValuesME
});

const mapDispatchToProps = dispatch => {
    return {
        onUpdate: (selected, dropdownValues) => dispatch({type: actionTypes.UPDATE_SELECTION, dataSelected: selected, dropdownValues:dropdownValues})
          }
};

export default connect(mapStateToProps, mapDispatchToProps)(DropdownSelect);

hey Jorge try to add conditions before mapping the data

        <DropdownMenu>
          {this.state.dropdownValues && this.state.dropdownValues.map(e => {return <DropdownItem key={e} onClick={this.changeDropdownValue}>{e}</DropdownItem>})}
        </DropdownMenu>

the same here

{this.state.dropdownValuesME && this.state.dropdownValuesME.map(e => {return <DropdownItem key={e} onClick={this.changeDropdownValueME}>{e}</DropdownItem>})}

and I believe you should not assign the state directly from the props, you should create the state as an empty array then in the component did mount you should set the state with the new values

  this.state = {
    dropdownOpen: false,
    solved: this.props.selectData,
    dropdownValues: [],

    dropdownOpenME: false,
    solvedME: this.props.selectDataME,
    dropdownValuesME: [],
  }
}

componentDidMount() {
  if(this.props.onRef)
  this.props.onRef(this);
  this.setState(oldState => {...oldState, dropdownValues: this.props.dropdownValues ,dropdownValuesME: this.props.dropdownValuesME})
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM