简体   繁体   中英

How to pass Slider Values to React Form when Slider is in a Component?

I'm working on a React application with Typescript. I created a multi-step form. Each form page is it's own component, and fields are separate components. I'm able to view data from Text Fields and Select Fields onSubmit, however, I get an error when I trying to accomplis the same with MUI Slider.

These are snippets of the format in the Main Form.

type FormData = {
  reading: string;
  math: string;
  science: string;
};

const INITIAL_DATA: FormData = {
  reading: "",
  math: "",
  science: "",
};

Hook to get User Data.

 const [data, setData] = useState(INITIAL_DATA);

  function updateFields(fields: Partial<FormData>) {
    setData((prev) => {
      return { ...prev, ...fields };
    });
  }

This is how I'm getting all of the steps. NOTE: I cleaned up irrelevant code. This focuses on just the parts that get data:

function getStepsContent(step: number) {
    switch (step) {
      case 0:
        return (
          <Scores
            {...data}
            updateFields={updateFields}
          />
        );
      case 1:
        return (
          <Personal
            {...data}
            updateFields={updateFields}
          />
        );
      default:
        return (
          <Personal
            {...data}
            updateFields={updateFields}
          />
        );
    }
  }

On the Personal Form Page, I have:

type ScoresData = {
  reading: string;
  math: string;
  science: string;
}

type ScoresProps = ScoresData & {
  updateFields: (fields: Partial<ScoresData>) => void
}

This is an example of the form field. Note: This is where I'm pulling in a custom field components. StyledSlider (uses MUI Slider).

<StyledSlider 
  label="Reading" 
  name="reading" 
  onChange={e => updateFields({reading: e.target.value})}
/>

This is my Slider Component. I've commented where I'm getting the error. Although there is an error, if I close out of the error window, I can see where the values are passing through to the form on submit. But I can't seem to get rid of the error.

interface StyledSliderProps {
  label: string;
  name: string;
  onChange: (event: SelectChangeEvent) => void;
}


export default function StyledSlider({ 
  label, 
  name, 
  onChange 
}: StyledSliderProps) {

  const [value, setValue] = useState(0);

  // NOTE: Ignoring case where Material UI allows an array of numbers.
  const handleSliderChange = (event: Event, newValue: number | number[], activeThumb: number) => {
    if (typeof newValue === "number") {
      setValue(newValue);
      onChange(event) //<---ERROR HERE
    }
  };

  // NOTE: Prevents re-rendering as the user moves along the slider.
  const handleSliderChangeCommitted = (
    event: Event | SyntheticEvent<Element, Event>,
    newValue: number | number[]
  ): void => {
    console.log("Value", newValue);
    console.log("Calculated Value", calculatedValue(value));
    if (typeof newValue === "number") {
      setValue(newValue);
    }
  };

  return (
    <Box>
      <Typography>{label}</Typography>
      <Slider
        aria-label="Restricted values"
        defaultValue={1}
        valueLabelFormat={valueLabelFormat}
        getAriaValueText={valuetext}
        marks={marks}
        name={name}
        value={value}
        scale={calculatedValue}
        step={null}
        onChange={handleSliderChange}
        onChangeCommitted={handleSliderChangeCommitted}
      />
    </Box>
  );
}

This is the error I'm getting.

Argument of type 'Event' is not assignable to parameter of type 'SelectChangeEvent<string>'.
  Type 'Event' is not assignable to type 'Event & { target: { value: string; name: string; }; }'.
    Type 'Event' is not assignable to type '{ target: { value: string; name: string; }; }'.
      Types of property 'target' are incompatible.
        Type 'EventTarget | null' is not assignable to type '{ value: string; name: string; }'.
          Type 'null' is not assignable to type '{ value: string; name: string; }'.

I've tried a few things, but it results in an error elsewhere.

I'm not sure what should go here or if this is actually the root of the problem:

onChange(event)

Passing two values instead of one did the trick.

In the StyledSlider component, I updated the onChange event to include the value.

interface StyledSliderProps {
  label: string;
  name: string;
  onChange: ((event: Event, value: number | number[]) => void);
}

Passed the second value to the onChange event in the handleSliderChange.

  const handleSliderChange = (
    event: Event, 
    newValue: number | number[]
  ): void => {
    if (typeof newValue === "number") {
      setValue(newValue as number);
      onChange(event, newValue)
    }
  };

And in the form field, I updated it like this:

<StyledSlider 
  label="Reading" 
  name="reading"
  onChange={(event: Event, value: number | number[]) => 
    updateFields({reading: (value as number).toString()})} 
/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM