1
votes

I'm currently working a a multipage checklist app to make a common checklist procedure more efficient.

my parent component called MainForm has all of the states for my app. In my first child element, I had to fill some text inputs. The states are updating and saving as planned. My second page (or other child element) was the portion where my checklist would begin. The issue is my app is rending, but the radiobutton value isn't being sent to my state. I'm also having an issue where I can select the 'yes' radio button and then the 'no' radio button, but I can't go from 'no' to 'yes'. radioGroup21 is the radio group that's giving me problem. All other states are working.

I'm getting an error in my console that says:

"Checkbox contains an input of type radio with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.

I've tried removing the value tag and the defaultValue line in my Radio elements, but no luck. I've tried creating constructor(props) in my parent element but I still kept having issues."

So far I've tried removing the defaultValue in my radio button and after I tried removing the value line. Unfortunately I this did not help.

I also read about controlled and uncontrolled inputs. I've tried changing my parent components state to put them in a constructor(props) bracket. But no luck.

I also tried to not use the handleChange function and use the setState function with values of {radioButton21 === 'yes'} but that didn't work.

//Parent Component
Class MainForm extends Component {

        state = {
            step: 1,
            projectNumber: '',
            projectName: '',
            numberOfSystems: '',
            buildSheet: '',
            controlPhilosophy: '',
            projectLayoutDrawing: '',
            projSoftwareValidation: '',
            CppDrawing: '',
            radioGroup21: '',
        }

    nextStep = () => {
        const { step } = this.state
        this.setState({
            step : step + 1
        })
    }

    prevStep = () => {
        const { step } = this.state
        this.setState({
            step : step - 1
        })
    }

    handleChange = input => event => {
        this.setState({ [input] : event.target.value })
    }

    render(){
        const {step} = this.state;
        const { projectNumber, projectName, numberOfSystems, buildSheet , controlPhilosophy, projectLayoutDrawing, projSoftwareValidation, CppDrawing, radioGroup21 } = this.state;
        const values = { projectNumber, projectName, numberOfSystems, buildSheet, controlPhilosophy, projectLayoutDrawing, projSoftwareValidation, CppDrawing, radioGroup21 };
        switch(step) {
        case 1:
            return <ProjectInfo 
                    nextStep={this.nextStep} 
                    handleChange = {this.handleChange}
                    values={values}
                    />
        case 2:
            return <PrelimInspection 
                    nextStep={this.nextStep}
                    prevStep={this.prevStep}
                    handleChange = {this.handleChange}
                    values={values}
                    />


export default MainForm;

-----------------------------------

//Child Component
import React, { Component } from 'react';
import { Form, Button, Radio } from 'semantic-ui-react';
import { throws } from 'assert';

class PrelimInspection extends Component{
    saveAndContinue = (e) => {
        e.preventDefault();
        this.props.nextStep();
    }

    back  = (e) => {
        e.preventDefault();
        this.props.prevStep();
    }

    render(){
        const { values } = this.props
        return(
        <Form color='blue' >
            <h1 className="ui centered">System Installation</h1>
            <Form.Field inline>
              <Form.Field>System Properly Supported</Form.Field>
              <Radio
                label = {'Yes'}
                name = {'radio21'}
                value = {'Yes'}
                onChange={this.props.handleChange('radioGroup21')}
                defaultValue={values.radioGroup21}
                />
              <Radio
                label = {'No'}
                name = {'radio21'}
                value = {'No'}
                onChange={this.props.handleChange('radioGroup21')}
                defaultValue={values.radioGroup21}
                />
            </Form.Field>
            <Button onClick={this.back}>Back</Button>
            <Button onClick={this.saveAndContinue}>Save And Continue </Button>
        </Form>
        )
    }
}

export default PrelimInspection

The app is rendering and the layout is correct. Unfortunately the state values aren't being sent to the parent state.

1
what's the ProjectInfo component? you only shared the code for PrelimInspectionTyro Hunter

1 Answers

0
votes

I checked the documentation https://react.semantic-ui.com/addons/radio/#types-radio-group and I have found few things you missed:

1.) Radio component asked the checked props (but you did not supply it).

2.) Which then requires you to pass the value, in your case it should come from the parent component:

<PrelimInspection
      valueFromParent={this.state["radioGroup21"]}
      nextStep={this.nextStep}
      handleChange={this.handleChange}
      values={values}
/>

so in your Child Component' render, take the value:

render() {
    const { values, valueFromParent } = this.props;
    ...

3.) Radio's onChange value is passed as the second param (obj.value).

<Radio
            label={'Yes'}
            name={'radio21'}
            value={"Yes"}
            checked={valueFromParent === 'Yes'}
            onChange={this.props.handleChange("radioGroup21")}
            ...
          />

So you can take the selected value like this:

// MainForm
  handleChange = input => (event, obj) => { // obj is the second param
    console.log("sendin here", input, obj.value);
    this.setState({ [input]: obj.value });
  };