简体   繁体   中英

How to update the state using react this.setState by directly passing in object

I am simply trying to get the text from the input field for which handler function is attached to a button and then just trying to store in input value into the state object.
But the state object doesn't store that value

 class EditTextArea extends React.Component { constructor() { super(); this.state = { message: "", }; this.handleButton = this.handleButton.bind(this); } handleButton(e) { const text = e.target.previousElementSibling.value; this.setState({ message: text }); console.log(this.state); } render() { return ( <div> <form> <input type="text" name="customText" /> <button type="button" onClick={this.handleButton}> Send </button> </form> </div> ); } } ReactDOM.render(<EditTextArea />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

Nothing in your render is using this.state.message , so you're not going to see anything happen. (Note that if you're wondering about the console.log of state, see this question's answers ; the update is asynchronous.)

If you actually use message , you see that it works:

 class EditTextArea extends React.Component { constructor(props) { super(props); this.state = { message: "", }; this.handleButton = this.handleButton.bind(this); } handleButton(e) { const text = e.target.previousElementSibling.value; this.setState({ message: text }); } render() { return ( <div> <div> Message is: {this.state.message} </div> <form> <input type="text" name="customText" /> <button type="button" onClick={this.handleButton}> Send </button> </form> </div> ); } } ReactDOM.render(<EditTextArea />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

Also note that you need to accept a parameter in your constructor and pass it to super() ; see above. That wasn't the problem, but it still still incorrect.

That said, I wouldn't do it that way. If you want an uncontrolled input , use a ref to access its value so you don't have to do the DOM traversal, which is easily broken with a small change to render :

 class EditTextArea extends React.Component { constructor(props) { super(props); this.state = { message: "", }; this.handleButton = this.handleButton.bind(this); this.inputRef = React.createRef(null); } handleButton() { const text = this.inputRef.current.value; this.setState({ message: text }); } render() { return ( <div> <div> Message is: {this.state.message} </div> <form> <input type="text" name="customText" ref={this.inputRef} /> <button type="button" onClick={this.handleButton}> Send </button> </form> </div> ); } } ReactDOM.render(<EditTextArea />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

Or you might consider a controlled component.

More about controlled vs. uncontrolled components hrere . More about refs here .

I run your script so initially, your message state taking an empty state just add a text and click a couple of times so Your message state is updating the second time. So if you need to dynamic change on input so I suggest you right an input handler and call it into the input change function and handle it separately.

 onInputchange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

I tried your code and it actually worked. But the problem is you cant change state and get changed state in same function, it reads the previus state. Just try to click button 2 times, you will see it works

In react states are updated asynchronously. To check your updated state you can check it by logging in render or in react developer tools.

According to you code you can check code given below

class EditTextArea extends React.Component {
    constructor() {
        super();
        this.state = {
            message: "",
        };
        this.handleButton = this.handleButton.bind(this);
    }

    handleButton(e) {
        const text = e.target.previousElementSibling.value;
        this.setState({ message: text });
        console.log(this.state);//It will show you old value
    }

    render() {
    console.log("check your updated state",this.state)
        return (
            <div>
                <form>
                    <input type="text" name="customText" />
                    <button type="button" onClick={this.handleButton}>
                        Send
                    </button>
                </form>
            </div>
        );
    }
}

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