Moe
Moe

Reputation: 1537

How to handle AutoComplete {onChange} in MUI v5 using a custom hook

I am using a custom hook that validates and handles the onChange function.

I have no issue handling the onChange for most of the Components (input, Select, TextField); I am using the following syntax to handle onChange Which is working fine except for AutoComplete.

None AutoComplete Components:

onChange = {handleInputChange}

const handleInputChange = (e) => {
    const { name, value } = e.target;
    setValues({
      ...values,
      [name]: value,
    });
    if (validateOnChange) validate({ [name]: value });
  };

Let's look at the e.target enter image description here

But when it's compared to the AutoComplete it looks nothing like the above screenshot. I am not able to get the name or the value to keep track of it correctly via setValues.

enter image description here

Upvotes: 1

Views: 4059

Answers (1)

Samira
Samira

Reputation: 2753

I used a function props :

const {onChange} = props;   

<Autocomplete
    onChange={(e, value) => onChange(value)}

if you want to see it completely :

import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import CircularProgress from '@mui/material/CircularProgress';
import {useRef} from "react";

export default function Asynchronous(props) {
    const {onChange, name, getListData, label = "name", id = "id", showName,defaultValue,disabled,required,value,noOption="No Option"} = props;
    const [open, setOpen] = React.useState(false);
    const [options, setOptions] = React.useState([]);
    const [filters, setFilters] = React.useState(null);
    const [loadingApi, setLoadingApi] = React.useState(false)
    const loading = open && options.length === 0;
    let timeOut = useRef(null);

    const getData = async (search = "") => {
        setLoadingApi(true)
        const data = await getListData(search); // For demo purposes.
        // console.log(data)
        setLoadingApi(false);
        // console.log(data)
        if(data)
        setOptions([...data]);
    }

    React.useEffect(() => {

        if (!loading) {
            return undefined;
        }
        getData();

    }, [loading]);

    React.useEffect(() => {
        if (filters !== null) {
            if (timeOut.current !== null)
                clearTimeout(timeOut.current);

            timeOut.current = setTimeout(() => getData(filters), 500);
        }
    }, [filters]);

    React.useEffect(() => {
        if (!open) {
            setOptions([]);
        }
    }, [open]);

    return (
        <Autocomplete
            disabled={disabled}
            id={name}
            name={name}
            sx={{width: "100%"}}
            open={open}
            onOpen={() => {
                setOpen(true);
            }}
            onClose={() => {
                setOpen(false);
            }}
            defaultValue={defaultValue}
            value={value}
            isOptionEqualToValue={(option, value) => option?.[id] === value?.[id]}
            getOptionLabel={(option) => option?.[label]}
            options={options}
            onChange={(e, value) => onChange(value)}
            loading={loadingApi}
            noOptionsText={noOption}
            renderInput={(params) => (
                <TextField variant="standard"
                    name={name}
                    required={required}
                    variant="standard"
                    {...params}
                    label={showName}
                    onChange={(e) => setFilters(e.target.value)}
                    InputProps={{
                        ...params.InputProps,
                        onblur:() => {},
                        endAdornment: (
                            <React.Fragment>
                                {loadingApi ? <CircularProgress color="inherit" size={20}/> : null}
                                {params.InputProps.endAdornment}
                            </React.Fragment>
                        ),
                    }}
                />
            )}
        />
    );
}

Upvotes: 1

Related Questions