KevinKipkemei
KevinKipkemei

Reputation: 43

A component is changing a controlled input of type undefined to be uncontrolled, why am I getting this?

const Message = () => {

    const [message, setMessage] = useState({ recipient: '', textmessage: ''})

    const sendText = () => {

        fetch(`http://127.0.0.1:4000/send-text?recipient=${message.recipient}&textmessage=${message.textmessage}`)
        .catch(err => console.error(err))
        console.log("Send Text is Running")
      }


      // console.log(message.recipient);
      // console.log(message.textmessage);



    return (
        <div>
            <h2> Send Text Message </h2>
          <label> Your Phone Number </label>
          <br />
          <input value={message.recipient}
            onChange={e => setMessage({recipient: e.target.value})} />
          <div/>
          <label> Message </label>
          <br />
          <textarea rows={3} value={message.textmessage}
            onChange={e => setMessage({textmessage: e.target.value })} />
          <div/>
          <button onClick={sendText}> Send Text </button>
        </div>
    )
}

export default Message;

When I input the number to update {message.recipient}, it's all good, but when I input on the textbox, to update the {message.textmessage} state, I get that error message. What am I doing wrong?

Upvotes: 1

Views: 190

Answers (2)

Gangadhar Gandi
Gangadhar Gandi

Reputation: 2252

Adding to Muhammad Zeeshan answer,

When we are developing class based components, we will use setState to update the state. Here State will be maintained.

state = {
   recipient: '', 
   textmessage: ''
};

onChange = (event) => {
  this.setState({recipent: event.target.value}); // here other state variables will be preserved
}

But with React Hooks, State will not be maintained. We have to manually preserve the other state variables.

const [message, setMessage] = useState({ recipient: '', textmessage: ''})
...
<input value={message.recipient}
            onChange={e => setMessage({...message, recipient: e.target.value})} />
---
---
<textarea rows={3} value={message.textmessage}
            onChange={e => setMessage({...message, textmessage: e.target.value })} />

Upvotes: 0

Muhammad Zeeshan
Muhammad Zeeshan

Reputation: 4748

You need to maintain the state. What you are doing here is losing the data that is previously set in the state while calling to setMessage.

You can do it this,

const Message = () => {

    const [message, setMessage] = useState({ recipient: '', textmessage: ''})

    const sendText = () => {

        fetch(`http://127.0.0.1:4000/send-text?recipient=${message.recipient}&textmessage=${message.textmessage}`)
        .catch(err => console.error(err))
        console.log("Send Text is Running")
      }

    return (
        <div>
            <h2> Send Text Message </h2>
          <label> Your Phone Number </label>
          <br />
          <input value={message.recipient}
            onChange={e => setMessage({ ...message, recipient: e.target.value})} />
          <div/>
          <label> Message </label>
          <br />
          <textarea rows={3} value={message.textmessage}
            onChange={e => setMessage({ ...message, textmessage: e.target.value })} />
          <div/>
          <button onClick={sendText}> Send Text </button>
        </div>
    )
}

Hope this works for you.

Upvotes: 1

Related Questions