2

I am trying to send data from Child Component to Parent component, using Typescript. There are lot of resources, but many don't explore typescript concept.

On the Parent, how would I set the ProductType event? Is this the proper way using React.ChangeEvent? We are using a dropdown selector with Material UI.

onProductTypeChange={(e: React.ChangeEvent<HTMLInputElement>) =>
         setProductType(e.target.value)}

Full Code:

Parent:

const ProductExport = () => {
 const [productType, setProductType] = useState<undefined | string>('');

 return (
 <>
 <ProductFilters
      productTypeValue={productType}
      onProductTypeChange={(e: React.ChangeEvent<HTMLInputElement>) =>
         setProductType(e.target.value)}
 />

Child:

type Props = {
  productTypeValue?: string;
  onProductTypeChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
};

const ProductFilters = ({
  productTypeValue,
  onProductTypeChange
}: Props) => {
  return (
    <Box>
      <Accordion>
        <AccordionSummary>
          <Typography>Products</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Box >
            <Box>
              <TextField
                select
                value={productTypeValue}
                onChange={onProductTypeChange}
                label={'Select Product Type'}
              >

2 Answers 2

7

Usually you hide the internal details in the Child (the actual event), and expose to the parent only the result (new data):

// Parent
const ProductExport = () => {
 const [productType, setProductType] = useState<undefined | string>('');

 return (
   <ProductFilters
      productTypeValue={productType}
      onProductTypeChange={setProductType}
   />
  );
}

// Child
type Props = {
  productTypeValue?: string;
  onProductTypeChange?: (newType: string) => void;
};

const ProductFilters = ({
  productTypeValue,
  onProductTypeChange
}: Props) => {
  return (
    <TextField
      select
      value={productTypeValue}
      onChange={(event) => onProductTypeChange?.(event.target.value)}
      label={'Select Product Type'}
    />
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

TS (and your IDE) should infer the type of event based on the type of the MUI <TextField> onChange prop
That is the advantage of keeping that event local: here it is inferred, you do not need to copy its type anywhere else.
3

React has a preprepared type for multiple event handlers, such ChangeEventHandler (TS playground):

type Props = {
  productTypeValue?: string;
  onProductTypeChange: ChangeEventHandler<HTMLInputElement>;
};

const ProductFilters = ({
  productTypeValue,
  onProductTypeChange
}: Props) => null;

const ProductExport = () => {
  const [productType, setProductType] = useState<undefined | string>('');

  const onProductTypeChange: ChangeEventHandler<HTMLInputElement> = e => setProductType(e.target.value);

  return (
    <ProductFilters
      productTypeValue={productType}
      onProductTypeChange={onProductTypeChange}
    />
  );
};

2 Comments

this is helpful, however its only changing the data type to something else, I appreciate it! what do you think of other answer btw from ghybs? both answers work
It's a good answer for a specific purpose component, such as your. It's less usable if you want to create a general input component, such as a custom input, and you want to preserver the controlled input api.

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.