Search code examples
reactjsformscomponentsmappingjsx

Radio buttons break with React JSX - Expressions must have one parent element


import React, { useEffect, useState } from 'react';
import { EmployeeList } from '../EmployeeList/EmployeeList';

export default function EmployeeMenu(props) {
    
    const [employeeList, setEmployeeList] = useState(() => new EmployeeList());
    useEffect(() => employeeList.getEmployees(), [employeeList]);

    const handleEmployeeChange = (event, data) => {
        props.setEmployee(event.target.value);
        console.log(event.target.value);
    }
    
    function EmployeeMenu() {
        let temp = employeeList.employees.map((employee) => (
        <div>
            <input type="radio" id={employee.phone_number} name="employee_name" value={employee.first_name} />
            <label htmlFor={employee.phone_number}>{employee.first_name} {employee.last_name}</label>
        </div>
        ));
        return temp;
    }

    return(
        <form onChange={handleEmployeeChange}>
            <EmployeeMenu />
        </form>
  );
}

code produces

This is what the code produces. It's close to what I wanted to accomplish, but my radio buttons do not check/uncheck when I select different employees.

That's because I have each input and label inside a separate div when I map the information from the employeeList array. But if I don't wrap them, I get "JSX expressions must have one parent element". Does anyone have any advice on how I could better map radio buttons from an array so that they remain inside the same form group?


Solution

  • inside the "form" element, it's must be type of form element(input).but div is not the type of form element, so it's has a warning. the code in below is right:

    <form onChange={handleEmployeeChange}>
         <input type="radio" id={employee.phone_number} name="employee_name" value={employee.first_name} />
         <label htmlFor={employee.phone_number}>{employee.first_name} {employee.last_name}</label>
     </form>
    

    if you want to package it as a component; your code should like:

    function EmployeeMenu() {
        let temp = employeeList.employees.map((employee) => (
        <>
            <input type="radio" id={employee.phone_number} name="employee_name" value={employee.first_name} />
            <label htmlFor={employee.phone_number}>{employee.first_name} {employee.last_name}</label>
        </>
        ));
        return temp;
    }
    
    return(
        <form onChange={handleEmployeeChange}>
            <EmployeeMenu />
        </form>
    );