6

in my react app I use radio buttons with this code:

 <RadioGroup name='steptype' className={css.ProcessStepRadioButtons} value={this.state.stepsData[stepNumber].stepType}
                                onChange={(value, event) => {
                                    this.changeInputOptionHandlerProcessStep(value, "stepType", stepNumber)
                                }}>
                        <RadioButton label={<T value='processes.new.processStepTypeDuty'/>} value={1} />
                        <RadioButton label={<T value='processes.new.processStepTypeVariable'/>} value={2}/>
                        <RadioButton label={<T value='processes.new.processStepTypeOptioanal'/>} value={3}/>
                    </RadioGroup>

and this handler:

export function changeInputOptionHandlerProcessStep(value, field, step) {
this.setState((prevState) => ({
    stepsData: prevState.stepsData.map((currentStep, i) => {
        if (i === step) {
            return {
                ...currentStep,
                [field]: value
            }
        }
        return currentStep
    })
}), () => {
    console.log("New state in ASYNC callback:", this.state.stepsData);
} );
}

State is set properly, but the radio buttons does not switch visually,

what could be the problem in this case?

thanks

UPDATE consolelog of this.state.stepsData

enter image description here

Update consolelog of this.state.stepsData right bevore renderenter image description here

Felix
  • 5,452
  • 12
  • 68
  • 163

1 Answers1

2

It seems your state design is not adequate for the RadioGroup component.

This is a controlled component behind the scenes, so the radio button selected is imposed at all times by RadioGroup's value prop. I don't know how you are initialising the component (meaning default selection), but its value should always belong to one of the values of the single RadioButton components, meaning that this.state.stepsData[stepNumber].stepType should be 1, 2 o 3.

stepType sounds to me (making assumptions here) like a string rather than a number, so it may be the initialisation is wrong and the component automatically resorts to the first radio button as the default selected.

Taking that into account, your substate for controlling this group of radio buttons should be a number (1, 2 or 3). Then, your handler changeInputOptionHandlerProcessStep will receive the new selection (new number) as first argument and you can just set the state with the new value. It would be something like:

<RadioGroup 
    name='steptype' 
    className={css.ProcessStepRadioButtons} 
    value={this.state.stepNumber} // initialised to 1, 2 or 3
    onChange={(value, event) => {this.changeInputOptionHandlerProcessStep(value, "stepType", stepNumber)}}
>
    <RadioButton label={<T value='processes.new.processStepTypeDuty'/>} value={1} />
    <RadioButton label={<T value='processes.new.processStepTypeVariable'/>} value={2}/>
    <RadioButton label={<T value='processes.new.processStepTypeOptioanal'/>} value={3}/>
</RadioGroup>

function changeInputOptionHandlerProcessStep(newValue) {
     this.setState({ stepNumber: newValue });
}

Let me know if that works for you.

rgommezz
  • 13,536
  • 2
  • 18
  • 23
  • Problem is that the stepNumber is in an Array I think. The logic I have above works but viually they don't change the bullets. – Felix Jun 14 '17 at 08:19
  • added a screenshot of this.state.stepsData above – Felix Jun 14 '17 at 08:23
  • Could you tell me what's the value of `stepNumber` initially, what's the default radio button selected and also which radio button do you click on that trigger the listener and the new state you screenshoted? – rgommezz Jun 14 '17 at 09:29
  • stepNumber is initially = 0 default radiobutton is the first one wth value 1 in state the stepType is set correctly when I click the second one in stepType there is now a 2 – Felix Jun 14 '17 at 09:36
  • 1
    ok, it would be great if you could provide a snapshot of your state before the handler is trigger, some `console.log` at the beginning of `render()` – rgommezz Jun 14 '17 at 09:40
  • Actually, how are you updating `stepNumber` after the handler code fired? I am guessing that's part of your state as well, something like `state.stepNumber` ? – rgommezz Jun 14 '17 at 09:50
  • from this the stepNumber comes. `const stepNumber = this.state.stepsData.length - 1;` stepNumber is not in state – Felix Jun 14 '17 at 09:53
  • I can't spot any errors, excepting for the fact that the 2 screenshots are inconsistent, after the trigger the length of the array is 2 and before is 1 and the state goes through a `map` operation, which doesn't change the length of the array. I am curious about how your handler is defined, you are referencing it using `this`, but then is defined as a separated function that you export (in a different file). Probably if you could paste the whole component code it would help – rgommezz Jun 14 '17 at 10:08
  • The length ist because in the First Screenshot Im have two steps and in the Second one I habe Only one – Felix Jun 14 '17 at 10:09
  • I've written my own radio buttons that sovled the problem – Felix Jun 16 '17 at 12:37