6

I'm building a React app with material-ui. I want to disable all my radio buttons in a RadioGroup when a certain event happens and re-enable them when the event goes away. (Say when I click a button, all radios are disabled, when I click the same button again, all radios are re-enabled.) I had the following conditional rendering snippet with a ternary operator which does the job but it looks really redundant. Is there a better way to do this? aka. Is there a way to make the prop (disable here) of a Material-ui component into a variable? Thanks!

                        const radioDisabled = false;

                        // Some mechanism here that could potentially 
                        // change the value of radioDisabled

                        { radioDisabled

                        ?

                            <RadioGroup row
                                value={value}
                                onChange={(e)=>{setValue(e.target.value)}}
                            >
                                <FormControlLabel
                                    value='1'
                                    checked={value === '1'}
                                    control={<Radio/>}
                                    label='1'
                                />
                                <FormControlLabel
                                    value='2'
                                    checked={value === '2'}
                                    control={<Radio/>}
                                    label='2'
                                />

                                      ...

                                <FormControlLabel
                                    value='n'
                                    checked={value === 'n'}
                                    control={<Radio/>}
                                    label='n'
                                />
                            </RadioGroup>

                        :

                            <RadioGroup row
                                value={value}
                                onChange={(e)=>{setValue(e.target.value)}}
                            >
                                <FormControlLabel
                                    disabled      // the only difference from above
                                    value='1'
                                    checked={value === '1'}
                                    control={<Radio/>}
                                    label='1'
                                />
                                <FormControlLabel
                                    disabled      // the only difference from above
                                    value='2'
                                    checked={value === '2'}
                                    control={<Radio/>}
                                    label='2'
                                />

                                      ...

                                <FormControlLabel
                                    disabled      // the only difference from above
                                    value='n'
                                    checked={value === 'n'}
                                    control={<Radio/>}
                                    label='n'
                                />
                            </RadioGroup>
Young
  • 739
  • 3
  • 9
  • 12
  • perhaps perform some iteration when rendering the jsx elements to remove redundancy – 95faf8e76605e973 Aug 27 '20 at 04:12
  • hmm.. I'm currently not sure how a loop should be done to fulfill my task here. Should I encapsulate my RadioGroup component into a separate component? But how can I insert the disabled prop when iterating through the FormControlLabel? – Young Aug 27 '20 at 04:19
  • Can you create a demo sandbox of your issue ? – Nidhi Dadiya Aug 27 '20 at 04:23

2 Answers2

5

Here are my 2 options to get rid of the redundancy:

1st option is you can opt to remove the ternary conditional rendering and instead render the disabled prop based on a condition e.g. disabled={radioDisabled}

const [radioDisabled, setRadioDisabled] = React.useState(false);

<FormControlLabel
  disabled={radioDisabled}
  value="1"
  checked={value === "1"}
  control={<Radio />}
  label="1"
/>

2nd option is you can iterate through the values/label of your radio input then assess if you need to disable or not, again, based on a condition

const [radioDisabled, setRadioDisabled] = React.useState(false);

const radioInputs = [
  {
    value: 1,
    label: 1
  },
  {
    value: 2,
    label: 2
  },
  {
    value: 3,
    label: 3
  }
];

{radioInputs.map((radioInput) => {
  return (
     <FormControlLabel
       disabled={radioDisabled}
       value={radioInput.value}
       checked={value == radioInput.value}
       control={<Radio />}
       label={radioInput.label}
     />
  );
})}

CodeSandBox: https://codesandbox.io/s/patient-worker-8mrq3?file=/src/App.js:1717-2041

95faf8e76605e973
  • 13,643
  • 3
  • 24
  • 51
  • Sorry for the late action though. Thank you for the highly parameterized FormControlLabel! I learned a lot. – Young Aug 31 '20 at 07:33
3
import { useState } from 'react'

const [isRadioDisabled, setIsRadioDisabled] = useState(false)

<Button title='Disables RadioButtons' 
  onPress={() => setIsRadioDisabled(prevState => !prevState)} />

    <RadioGroup row
      value={value}
      onChange={(e)=>{setValue(e.target.value)}}
      >
        <FormControlLabel
          disabled={radioDisabled}
          value='1'
          checked={value === '1'}
          control={<Radio/>}
          label='1'
        />
        <FormControlLabel
          disabled={radioDisabled}
          value='2'
          checked={value === '2'}
          control={<Radio/>}
          label='2'
        />

        <FormControlLabel
          disabled={radioDisabled}
          value='n'
          checked={value === 'n'}
          control={<Radio/>}
          label='n'
        />
    </RadioGroup>

Use React's useState hook to toggle between states to disable and enable FormControlLabels. Instead of using a variable or prop. Then, use a button to toggle between the true and false of the created state as shown above. There's no need to conditionally render them, since the disabled prop accepts a boolean to toggle from false to true.

Tom Bombadil
  • 3,455
  • 1
  • 13
  • 24
  • Thank you for the answer! I learned a lot form your answer. I set the other one as taken answer simply because the other answer was posted earlier. – Young Aug 31 '20 at 07:36
  • 1
    @Young I'm happy you learned something new from the answer. Also, if you want to take your programming to the next level, start off with Typescript -> https://www.youtube.com/watch?v=WBPrJSw7yQA&t=11s He's a very good teacher. Also, Ben -> https://www.youtube.com/watch?v=I6ypD7qv3Z8&t=47168s for fullstack development. Wish you the best. – Tom Bombadil Aug 31 '20 at 08:56
  • Really appreciate it! – Young Aug 31 '20 at 10:20