1

I have the following:

interface Message {
  message?: {
    title?: string;
    description?: string;
    body?: string;
  };
}

const [message, setMessage] = useState<Message>({
    message: {
      title: "",
      description: "",
      body: "",
    },
  });

and I'm trying to handle my form in this method where I fill the form with newly created values:

  const handleMessageInput = (
    event: React.ChangeEvent<HTMLInputElement>,
    field: keyof Message
  ) => {
    setMessage({
      ...message,
      [field]: event.target.value,
    });
  };

 <input
            onChange={(e) => handleMessageInput(e, "title")}
            ref={(node) => {
              input = node;
            }}
          />

 <input
            onChange={(e) => handleMessageInput(e, "body")}
            ref={(node) => {
              input = node;
            }}
          />

 <input
            onChange={(e) => handleMessageInput(e, "description")}
            ref={(node) => {
              input = node;
            }}
          />

but the problem is when I submit the form I dont get my values means my state is not updated with the created values, which I think I missed something within extracting the fields, also is there a way to avoid using ref for each field I have ? so any help ?

UPDATE:

enter image description here

1 Answer 1

1

Hey when create a state you defined it like this:

useState<Message>({
    message: {
      title: "",
      description: "",
      body: "",
    },
})

but then when you updating it you do like this:

setMessage(
 {
   ...message,
   [field]: event.target.value
 }
)

See the difference? it supposed to be like this:


setMessage(
 {
   message: {
     ...message.message,
     [field]: event.target.value
   }
 }
)

This way you will update the right thing, otherwise you are crating new fields near the message level of your object but you want to update the fields inside the message field in your object

EDIT:

To fix the error, you need to introduce a deep level type so when you say keyof it will refer to the right keys.

  interface MessageFormValues {
    title?: string
    description?: string
    body?: string
  }

  interface Message {
    message: MessageFormValues
  }

  const handleMessageInput = (
    event: React.ChangeEvent<HTMLInputElement>,
    field: keyof MessageFormValues,
  ) => {
    setMessage({
      message: {
        ...message.message,
        [field]: event.target.value,
      }
    })
  }

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

9 Comments

The strange thing is that why TypeScript is not throwing any warnings at you.
thanks for the help, I didnt catched that, but we get another error after that which I added an update to it to my question, take a look pls
@A.H Hey I included the EDIT with the fix for this, you just remove message as a top level, because you don't really need this, and it will also fix your problem with this new error, let me know if it helps
hey, I cannot change the sctructure of my interface cause I have a specific type which I need to match for my backend ;). so this is kind of impossible now
and now it worked! thanks dude ;) but another thing, do you have any idea how to avoid using ref in every input ? and make a generic one ?
|

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.