2

I'm trying to render components based on the checkbox selection. My approach was as follows:

class ReportMainCat extends Component {    
    constructor(props) {
        super(props);   
        this.report_next = this.report_next.bind(this);    
    };

    report_next() {    
        if(this.refs.sexual.checked) {
            return <PostOptionBar/>   
        }    
    }

    render() {            
        return (
            <div className="text_align_left">   
                <div className="width_100 margin_bottom10px">
                    <input type="checkbox"  ref="sexual"/>
                    <a>Sexual Content</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="selfharm"/>
                    <a>Threat or self harm</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="abuse"/>
                    <a>Abuse or bullying</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="illegal"/>
                    <a>Illegal substances</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="discrimination"/>
                    <a>Discrimination</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="copyright"/>
                    <a>Copyright or spam</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="nopermission"/>
                    <a>Humiliating, embarassing or posted without permission</a>
                </div>

                <button className="float_right" onClick={this.report_next}>Next</button>

                {this.report_next()}

            </div>        
        )    
    }
}

I'm checking if the checkbox is checked and rendering the component accordingly, but I keep getting this error:

Uncaught TypeError: Cannot read property 'checked' of undefined

How do I fix this? Or is this the best approach to do what I want to do?

Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
CraZyDroiD
  • 6,622
  • 30
  • 95
  • 182

4 Answers4

2

It's advised not to use string refs in react components.

https://facebook.github.io/react/docs/refs-and-the-dom.html

So refs must be used in this manner

 ref={(input) => { this.textInput = input; }}

So your input tag should be something like this

<input type="checkbox" ref={(input) => { this.sexualInput = input; }} />

And then in report_next() function you can get that value by using.

this.sexualInput.checked

Also do try to avoid using so many refs. Use state as much as possible in react components.

JiN
  • 818
  • 1
  • 7
  • 14
1

Suggestion As per DOC:

If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. If you're currently using this.refs.textInput to access refs, we recommend the callback pattern instead.

Changes:

1. Returning a component on click of button will not do anything, for that you need to define a separate function just for onClick.

2. You need to use some state variable otherwise component will not re-rendered automatically and onclick of button you need to update that state value.

Check this snippet:

class ReportMainCat extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
           renderComponent: false
        }
        this.buttonClick = this.buttonClick.bind(this);
    };

    report_next(){
        if(this.refs.sexual && this.refs.sexual.checked){
            return <div> hello </div>
        }
    }
    
    buttonClick(){
       this.setState({
          renderComponent: true
       })
    }

    render() {
        return (
            <div className="text_align_left">

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox"  ref="sexual"/>
                    <a>Sexual Content</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="selfharm"/>
                    <a>Threat or self harm</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="abuse"/>
                    <a>Abuse or bullying</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="illegal"/>
                    <a>Illegal substances</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="discrimination"/>
                    <a>Discrimination</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="copyright"/>
                    <a>Copyright or spam</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="nopermission"/>
                    <a>Humiliating,embarassing or posted without permission</a>
                </div>

                <button className="float_right" onClick={this.buttonClick}>Next</button>

                {this.report_next()}
            </div>
        )
    }
}

ReactDOM.render(<ReportMainCat/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
0

Use the SyntheticEvent, 'e'. Below is an example:

const element1 = "male";
const element2 = "female";

<input
 type="checkbox"
 name={element1}
 value={element1}
 onChange={this.handleChange}
/>
<label for="element" style={{ fontSize: 35 }}>
{element2}
 </label>

<input
 type="checkbox"
 name={element2}
 value={element2}
 onChange={this.handleChange}
/>
<label for="element" style={{ fontSize: 35 }}>
{element2}
 </label>




handleChange = (e) => {
// to find out if it's checked or not; returns true or false
const checked = e.target.checked;

// to get the checked value
const checkedValue = e.target.value;

// to get the checked name
const checkedName = e.target.name;

//then you can do with the value all you want to do with it.
};
Anayo Oleru
  • 468
  • 5
  • 8
-1

class ReportMainCat extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
           renderComponent: false
        }
        this.buttonClick = this.buttonClick.bind(this);
    };

    report_next(){
        if(this.refs.sexual && this.refs.sexual.checked){
            return <div> hello </div>
        }
    }
    
    buttonClick(){
       this.setState({
          renderComponent: true
       })
    }

    render() {
        return (
            <div className="text_align_left">

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox"  ref="sexual"/>
                    <a>Sexual Content</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="selfharm"/>
                    <a>Threat or self harm</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="abuse"/>
                    <a>Abuse or bullying</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="illegal"/>
                    <a>Illegal substances</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="discrimination"/>
                    <a>Discrimination</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="copyright"/>
                    <a>Copyright or spam</a>
                </div>

                <div className="width_100 margin_bottom10px">
                    <input type="checkbox" ref="nopermission"/>
                    <a>Humiliating,embarassing or posted without permission</a>
                </div>

                <button className="float_right" onClick={this.buttonClick}>Next</button>

                {this.report_next()}
            </div>
        )
    }
}

ReactDOM.render(<ReportMainCat/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min`enter code here`.js"></script>

<div id='app'/>
test
  • 1
  • 1
    Can you explain the solution ? Also note that `this.refs` [has issues](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs). – kca Dec 07 '20 at 10:19
  • i am also searching for the answer – test Dec 07 '20 at 11:57