Material-UI Slider not drag when loading component from a switch

Viewed 1195

I am working on functionality where there is a set of radio buttons that change the state and determines which components should be active. I think I am close and the values all get set as they should but the slider will not slide, you have to click it in to position. I have a sandbox of what I am talking about here :

https://codesandbox.io/s/elated-banach-k1i4y?file=/src/Form.js

You will see that the radio reveals the appropriate slider. If you click the TEST button you can see that the correct value gets set to the object. I also added another Slider outside of the switch render method and you can see that works as expected.

Also here is the code I am using

    import React, { Fragment, useState } from "react";
    import {
      Radio,
      RadioGroup,
      FormControlLabel,
      FormControl,
      Typography,
      Slider,
      Button
    } from "@material-ui/core/";

    export default function CreateForm() {
      const defaultValues = {
        a: 0,
        b: 0,
        c: 0
      };

      const [radioValue, setValue] = useState("");
      const [activity, setActivity] = useState(defaultValues);

      const handleRadioChange = (e) => {
        const { value } = e.target;
        setValue(value);
        setActivity(defaultValues);
      };

      const handleSlider = (name) => (e, value) => {
        setActivity({
          ...activity,
          [name]: value
        });
      };

      function RadioButtonsGroup() {
        return (
          <RadioGroup
            aria-label="group"
            name="group"
            value={radioValue}
            onChange={handleRadioChange}
            row
          >
            <FormControlLabel
              name="group"
              value="a"
              control={<Radio />}
              label="A"
            />
            <FormControlLabel
              name="group"
              value="b"
              control={<Radio />}
              label="B"
            />
          </RadioGroup>
        );
      }

      function test() {
        console.log(activity);
      }

      function RenderSwitch(radioValue) {
        switch (radioValue.value) {
          case "a":
            return <GetA />;
          case "b":
            return <GetB />;
          default:
            return <p>Select Radio</p>;
        }
      }

      function GetA() {
        return (
          <React.Fragment>
            <Typography id="discrete-slider" gutterBottom>
              A
            </Typography>

            <Slider
              value={activity.a}
              aria-labelledby="discrete-slider"
              valueLabelDisplay="auto"
              step={10}
              marks
              min={10}
              max={120}
              name="a"
              onChange={handleSlider("a")}
              style={{ marginBottom: "20px" }}
            />
          </React.Fragment>
        );
      }

      function GetB() {
        return (
          <Fragment>
            <Typography id="discrete-slider" gutterBottom>
              B
            </Typography>

            <Slider
              value={activity.b}
              aria-labelledby="discrete-slider"
              valueLabelDisplay="auto"
              step={10}
              marks
              min={10}
              max={120}
              name="a"
              onChange={handleSlider("b")}
              style={{ marginBottom: "20px" }}
            />
          </Fragment>
        );
      }

      return (
        <>
          <form noValidate onSubmit={(e) => e.preventDefault()}>
            <FormControl>
              <RadioButtonsGroup />
              <RenderSwitch value={radioValue} />
              <Button
                fullWidth
                variant="contained"
                color="primary"
                type="submit"
                onClick={test}
              >
                TEST
              </Button>

              <Typography
                style={{ marginTop: "40px" }}
                id="discrete-slider"
                gutterBottom
              >
                One more to show how drag works here
              </Typography>

              <Slider
                value={activity.c}
                aria-labelledby="discrete-slider"
                valueLabelDisplay="auto"
                step={10}
                marks
                min={10}
                max={120}
                name="c"
                onChange={handleSlider("c")}
              />
            </FormControl>
          </form>
        </>
      );
    }
1 Answers

You have to handle the sliders' state change inside their own elements like so (Sandbox):

const SliderA = () => {
  const [activity, setActivity] = useState(0);

  const handleChange = (event, newValue) => {
    setActivity(newValue);
  };

  return (
    <React.Fragment>
      <Typography id="discrete-slider" gutterBottom>
        A
      </Typography>

      <Slider
        value={activity}
        aria-labelledby="discrete-slider"
        valueLabelDisplay="auto"
        step={10}
        marks
        min={10}
        max={120}
        name="a"
        onChange={handleChange}
        style={{ marginBottom: "20px" }}
      />
    </React.Fragment>
  );
};
Related