javascript - React Autocomplete with Material UI - Stack Overflow

I'm implementing a ponent Autoplete using Material UI library.But there's a problem - I'

I'm implementing a ponent Autoplete using Material UI library.

But there's a problem - I'm not sure how to pass value and onChange properly, because I have a custom implementation of TextField that requires value and onChange as well. Should I pass value and onChange twice - to Autoplete and TextField? Or maybe there's a better solution? Would appreciate any help! Here's my code:

import { Autoplete as MuiAutoplete } from '@material-ui/lab'
import { FormControl } from 'ponents/_helpers/FormControl'
import { useStyles } from 'ponents/Select/styles'
import { Props as TextFieldProps, TextField } from 'ponents/TextField'

export type Props = Omit<TextFieldProps, 'children'> & {
  options: Array<any>
  value: string
  onChange: (value: string) => void

  disabled?: boolean
}

export const Autoplete = (props: Props) => {
  const classes = useStyles()

  return (
    <FormControl
      label={props.label}
      error={props.error}
      helperText={props.helperText}
    >
      <MuiAutoplete
        options={props.options}
        // value={props.value}
        // onChange={event =>
        //   props.onChange((event.target as HTMLInputElement).value as string)
        // }
        classes={{
          option: classes.menuItem,
        }}
        disabled={props.disabled}
        getOptionLabel={option => option.label}
        renderInput={params => (
          <TextField
            {...params}
            placeholder={props.placeholder}
            value={props.value}
            onChange={props.onChange}
          />
        )}
        renderOption={option => {
          return <Typography>{option.label}</Typography>
        }}
      />
    </FormControl>
  )
}```

I'm implementing a ponent Autoplete using Material UI library.

But there's a problem - I'm not sure how to pass value and onChange properly, because I have a custom implementation of TextField that requires value and onChange as well. Should I pass value and onChange twice - to Autoplete and TextField? Or maybe there's a better solution? Would appreciate any help! Here's my code:

import { Autoplete as MuiAutoplete } from '@material-ui/lab'
import { FormControl } from 'ponents/_helpers/FormControl'
import { useStyles } from 'ponents/Select/styles'
import { Props as TextFieldProps, TextField } from 'ponents/TextField'

export type Props = Omit<TextFieldProps, 'children'> & {
  options: Array<any>
  value: string
  onChange: (value: string) => void

  disabled?: boolean
}

export const Autoplete = (props: Props) => {
  const classes = useStyles()

  return (
    <FormControl
      label={props.label}
      error={props.error}
      helperText={props.helperText}
    >
      <MuiAutoplete
        options={props.options}
        // value={props.value}
        // onChange={event =>
        //   props.onChange((event.target as HTMLInputElement).value as string)
        // }
        classes={{
          option: classes.menuItem,
        }}
        disabled={props.disabled}
        getOptionLabel={option => option.label}
        renderInput={params => (
          <TextField
            {...params}
            placeholder={props.placeholder}
            value={props.value}
            onChange={props.onChange}
          />
        )}
        renderOption={option => {
          return <Typography>{option.label}</Typography>
        }}
      />
    </FormControl>
  )
}```
Share Improve this question edited Apr 4 at 13:50 Olivier Tassinari 8,6916 gold badges25 silver badges28 bronze badges asked Jun 22, 2021 at 15:50 Anna HarshynaAnna Harshyna 932 silver badges8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Material UI has props built in to handle the state of the Autoplete vs input values.

You can see it in use in the docs here: https://material-ui./ponents/autoplete/#controllable-states

In your example, you would want to add the inputChange and onInputChange props to the Autoplete ponent. These will get passed down to your TextField through the params passed to the renderInput function.

So your final code would look something like the below snippet copied from the linked documentation:

<Autoplete
  value={value}
  onChange={(event, newValue) => {
    setValue(newValue);
  }}
  inputValue={inputValue}
  onInputChange={(event, newInputValue) => {
    setInputValue(newInputValue);
  }}
  id="controllable-states-demo"
  options={options}
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="Controllable" variant="outlined" />}
/>
import React, { useEffect, useState } from "react";
import { Autoplete } from "@mui/material/node";
import { Controller, useFormContext } from "react-hook-form";
import { TextField } from "@mui/material";
import PropTypes from "prop-types";

 const valueFunc = (arr, id) => {
  const temp = arr.length > 0 && arr?.find((element) => element.id === id);
  return temp;
};

AutopleteSearch.propTypes = {
  options: PropTypes.arrayOf({
    title: PropTypes.string,
    id: PropTypes.string,
  }),
  name: PropTypes.string,
};

export default function AutopleteSearch({
  name,
  options,
  label,
  id,
  ...other
}) {
  const [temp, setTemp] = useState({});
  const { control, setValue } = useFormContext();

  useEffect(async () => {
    const found = valueFunc(options, id);
    await setTemp(found);
  }, [options, id]);

  return (
    <Controller
      control={control}
      name={name}
      rules={{ required: true }}
      render={({ fieldState: { error } }) => (
        <>
          <div >
            <Autoplete
              id="controllable-states-demo"
              onChange={(_, v) => {
                setValue(name, v?.id);
                setTemp(v);
              }}
              onBlur={(e) => {
                e.target.value == "" && setValue(name, "");
              }}
              value={temp}
              options={options}
              getOptionLabel={(item) => (item.title ? item.title : "")}
              renderInput={(params) => (
                <>
                  <TextField
                    {...params}
                    label={label}
                    InputLabelProps={{
                      style: {
                        fontSize: "14px",
                        fontWeight: "400",
                        color: "#FF5B00",
                      },
                    }}
                 
                    size="small"
                    error={temp === null && !!error}
                    helperText={temp === null && error?.message}
                    {...other}
                  />
                </>
              )}
            />
          </div>
        </>
      )}
    />
  );
}
 <AutopleteSearch
   name="pharmacy_group_title"
   label="Pharmacy Group" 
   options={pharmacyGroups}                           // Array  {id , title}   
   id={defaultValues?.pharmacy_group_title}           // ID
  />

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744288032a4566894.html

相关推荐

  • javascript - React Autocomplete with Material UI - Stack Overflow

    I'm implementing a ponent Autoplete using Material UI library.But there's a problem - I'

    8天前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信