javascriptreactjsmaterial-uijsxreact-props

Custom MUI fields (<TextField />) not recognizing a change in value


I'm trying to create custom form components so I don't need to update every item if I decide on a style change.The ReportSelect version does not update the value upon selection of a menu item, and the ReportTextField only works for the first instance (setting the value, that is). Is there a way to do this? I tried using styled() initially but I couldn't figure out how to give it the properties of fullwidth, variant, etc.

Here are my components

export const ReportSelect = (props) => {
  return (
    <TextField 
    select
    fullWidth
    variant='filled'
    margin='dense'
    size='small'
    label={props.label}
    value={props.value}
    onChange={props.set}>
      
      {props.items.map(item => (
        <MenuItem key={item} value={item}>{item}</MenuItem>
      ))}

    </TextField>
  );
}

export const ReportTextField = (props) => {
return (
    <TextField 
       fullWidth
       type='text'
       id='filled-basic'
       variant='filled'
       label={props.label}
       value={props.value}
       onChange={props.set}
    />
    );
};

and here is how I use it:

<ReportSelect
  label="Sex"
  value={sex}
  onChange={(e) => setSex(e.target.value)}
  items={['Female', 'Male']}
/>

<ReportTextField
  label="Last Name"
  value={lastName}
  onChange={(e) => setLastName(e.target.value)}
/>

The drop down shows both options and visually everything is there, but the value just won't update upon selection. And for the later, only the first instance updates the value, additional form components with the same tag do not work.


Solution

  • Your issue seems to be related to the properties you're passing down to your custom components and how they are handled inside the components themselves. Specifically, there's a mismatch in naming the onChange prop in the ReportSelect component and possible issues with how the value and onChange are managed.

    const ReportSelect = ({ label, value, onChange, items }) => {
      return (
        <TextField 
          select
          fullWidth
          variant='filled'
          margin='dense'
          size='small'
          label={label}
          value={value}
          onChange={onChange}
        >
          {items.map(item => (
            <MenuItem key={item} value={item}>{item}</MenuItem>
          ))}
        </TextField>
      );
    };
    
    const ReportTextField = ({ label, value, onChange }) => {
      return (
    <TextField 
      fullWidth
      type='text'
      variant='filled'
      label={label}
      value={value}
      onChange={onChange}
    />
      );
    };