1

I have a react select component with a handlechange that simply needs to update the state

When I click on the select option I get this error

TypeError: Cannot read property 'name' of undefined

The issue is with the react select when trying to update the group piece of state.

Any ideas? I cant seem to figure this one out and i need to type more here so that i can submit my question just disregard what I am typing here below. I used to be an adventurer like you, then I took an arrow in the knee, just ask any of my fellow guards and they'll tell you thats its true, We all took an arrow in the knee. Let me guess someone stole your sweetrolls?

here is my contact create component below

import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { toast } from 'react-toastify';
import Select from 'react-select';
import makeAnimated from 'react-select/animated';
import { createContact } from '../../actions/index';
import { Button, Form, FormGroup, Input, Label } from 'reactstrap';
import Divider from '../common/Divider';
import 'react-phone-input-2/lib/style.css';
import PhoneInput from 'react-phone-input-2';

const ContactForm = ({ hasLabel }) => {
  const dispatch = useDispatch()
  // State
  const [contact, setContact] = useState({ 
    phone_number: '',
    phone_type: 'mobile',
    group: '',        <------- this is giving error
    firstName: '',
    lastName: '',
    company: '',
    email: '',
    error: '',
    open: false})
  
  const [isDisabled, setIsDisabled] = useState(true);
  
  // Handler
   const handleSubmit = e => {
    e.preventDefault()
    dispatch(createContact(contact))
   };

  
  const handleChange = e => {
    setContact({...contact, [e.target.name]: e.target.value})
  };
  
  const groups = useSelector((state) => state.groups)
  

  useEffect(() => {
  
    setIsDisabled( !contact.phoneNumber || !contact.phoneType);
  }, [contact.phoneNumber, contact.phoneType ]);

  return ( 
  <>
    <Form onSubmit={handleSubmit}>
      
      <FormGroup>
        <Label>Enter a Number</Label>
       
        <PhoneInput 
        
            country="us"
            isValid={(value, country) => {
              if(value.match(/12345/)) {
                return 'Invalid value: '+value+', '+country.name;
              } else if (value.match(/1234/)) {
                return false
              } else {
                return true;
              }
            }}
            inputStyle={{border: 'none', font: 'caption' }}
            inputClass="w-100 font-weight-bold"
            containerClass="rounded text-sm shadow focus:outline-none focus:shadow-outline dark"
            countryCodeEditable={false}
            dropdownClass="rounded"
            preferredCountries={['us','ca','mx','fr','it','br','co','it','gr']}
            limitMaxLength={true}
            enableSearch={true}
            name="phone_number"
            value={contact.phone_number.value}
            onChange={phone_number => setContact({...contact, phone_number: phone_number})}
           
        />
       
      </FormGroup>
      <div>
        <FormGroup>
          <Label>Phone type</Label>
          <Input
            placeholder={!hasLabel ? 'landline or mobile' : ''}
            name="phone_type"
            required={true}
            value={contact.phone_type.value}
            onChange={handleChange}
            type='select'>

          <option name="mobile" value="mobile">Mobile</option>
          <option name="landline" value="landline">Landline</option>
          </Input>
        </FormGroup>
      </div>
      <div>
        <FormGroup>
        <Label>
          Choose Group/List</Label>
            <Select
              name="group"
              required={true}
              className="mb-3"
              closeMenuOnSelect={false}
              options={groups}
              getOptionLabel={({title}) => title}
              getOptionValue={({_id}) => _id}
              onChange={handleChange}.         <----ignore the period this is where the issue lies   
              isMulti
              placeholder="Add to a Group"
              isSearchable={true}
            />
        </FormGroup>
      </div>
     
      <div>
        <FormGroup>
          <Label>First Name</Label>
          <Input
            
            placeholder={!hasLabel ? 'First Name' : ''}
            name="firstName"
            value={contact.firstName.value}
            onChange={handleChange}
            type='input'
          />
        </FormGroup>
      </div>
      <div>
        <FormGroup>
          <Label>Last Name</Label>
          <Input
            placeholder={!hasLabel ? 'Last Name' : ''}
            name="lastName"
            value={contact.lastName.value}
            onChange={handleChange}
            type='input'
          />
        </FormGroup>
      </div>
      <div>
        <FormGroup>
          <Label>Company</Label>
          <Input
            placeholder={!hasLabel ? 'Company' : ''}
            name="company"
            value={contact.company.value}
            onChange={handleChange}
            type='input'
          />
        </FormGroup>
      </div>
      <div>
        <FormGroup>
          <Label>Email</Label>
          <Input
            placeholder={!hasLabel ? 'Email' : ''}
            name="email"
            value={contact.email.value}
            onChange={handleChange}
            type='email'
          />
        </FormGroup>
      </div>
  
      <Divider className="mt-4">or save without adding</Divider>   
      <FormGroup>
      <Button block color="primary" type="submit">Save</Button>
      </FormGroup>
    </Form>
  
  </>
 
    
  );
};

ContactForm.propTypes = {
  
  hasLabel: PropTypes.bool
};

ContactForm.defaultProps = {
  layout: 'basic',
  hasLabel: false
};

export default ContactForm;

1 Answer 1

2

By looking at the docs here https://github.com/JedWatson/react-select/tree/master/packages/react-select I'd guess this is because react-select onChange doesn't return an event with a target, but just returns the value of whatever is selected. It probably acts differently to <Input>, So you should create a new function. If all you're doing is setting the selected value to state then you can just use an arrow function.

I think this should work, or something like it (I haven't tested this)

<Select 
    name="group" 
    required={true} 
    className="mb-3" 
    closeMenuOnSelect={false}
    options={groups}
    getOptionLabel={({title}) => title}
    getOptionValue={({_id}) => _id}
    onChange={(selectedGroup) => 
        {setContact({...contact, group: selectedGroup})}}         
    isMulti
    placeholder="Add to a Group"
    isSearchable={true}
/>

If this doesn't work, use your original function and console.log(e) and you will probably be able to figure it out from there.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I will test this and get back shortly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.