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?

3
  • It looks like the ref object is not built before this line: {this.report_next()} Commented Jun 9, 2017 at 9:53
  • If so, how do i fix it? Commented Jun 9, 2017 at 9:56
  • follow this one man stackoverflow.com/questions/36833192/… Commented Jun 9, 2017 at 10:05

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

Comments

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'/>

Comments

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.
};

Comments

-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'/>

2 Comments

Can you explain the solution ? Also note that this.refs has issues.
i am also searching for the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.