简体   繁体   中英

ReactJS: Cannot read property 'value' of null when getting selected value

What I want to do is get the value of the selected <option> from the <select> elemenet however in my current code, I keep getting an error saying:

cannot read property 'value' of null.

This is very frustrating considering I've tried the methods I found online and yet it still doesn't work properly. Any help would be appreciated, thanks!

import React, { Component } from 'react'

class MyClass extends Component{
    constructor(props){
        super(props);

        this.state = {
            selectedItem: ""
        };
    }

    onChange() {
        var selectedItem = document.getElementById("selectItem").value
        this.setState({selectedItem: selectedItem})
    }

    render(){
        return (
            <div style={{textAlign: "center"}}>
                <select id="selectItem" defaultValue="option1" onChange={this.onChange()}>
                    <option value="option1">option1</option>
                    <option value="option2">option2</option>
                    <option value="option3">option3</option>
                    <option value="option4">option4</option>
                </select>

                <div>{this.state.selectedItem}</div>
            </div>
        )
    }
}

export default MyClass

I would like it to display what option is being selected within the div. If possible I would also like it to show the defaultValue upon loading the page as well.

The reason this isn't working is because the context of onChange is not that of your MyClass component instance, meaning that when onChange is called, this won't be the corresponding instance of MyClass .

The problem can be resolved by adding this line to your constructor:

constructor(props){
    super(props);

    this.state = {
        selectedItem: ""
    };

    // Add this
    this.onChange = this.onChange.bind(this);
}

Update

One way to load the default value of the <select> dynamically:

class MyClass extends Component{
    constructor(props){
        super(props);

        this.state = {
            selectedItem: ""
        };
    }

    componentDidMount() {

        /* Set initally selected value to say, option3 */
        this.setState({ selectedItem : "option3" })
    }

    onChange() {
        var selectedItem = document.getElementById("selectItem").value
        this.setState({selectedItem: selectedItem})
    }

    render(){
        return (
            <div style={{textAlign: "center"}}>
                {/* 
                Specify the select value which will show as option3 by
                default 
                */}
                <select id="selectItem" value={ this.selectedItem }
                        onChange={this.onChange()}>
                    <option value="option1">option1</option>
                    <option value="option2">option2</option>
                    <option value="option3">option3</option>
                    <option value="option4">option4</option>
                </select>

                <div>{this.state.selectedItem}</div>
            </div>
        )
    }
}

The problem is that you're calling this.onChange while the element is created, while the onChange attribute is set ( onChange={this.onChange()} ).

You should use just onChange={this.onChange} (without the parenthesis () ).

Beside that, document.getElementById is not how you access the DOM in a ReactJS app, actually, you don't need to access the DOM in this case.

import React, { Component } from 'react'


class MyClass extends Component{
    state = {
        selectedItem: ""
    };

    onChange = ({ target: { value } }) => {
        this.setState({ selectedItem: value })
    }

    render(){
        return (
            <div style={{textAlign: "center"}}>
                <select id="selectItem" defaultValue="option1" onChange={this.onChange}>
                    <option value="option1">option1</option>
                    <option value="option2">option2</option>
                    <option value="option3">option3</option>
                    <option value="option4">option4</option>
                </select>

                <div>{this.state.selectedItem}</div>
            </div>
        )
    }
}

export default MyClass

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM