I have an h1
element in my React app that I plan to use with a contentEditable
attribute to allow users to edit it directly. The problem is within the useFormValues
hook that I use to manage all my other inputs, we are unable to access the e.target.name
or e.target.value
properties the way we are with a standard input. [Note: Please don’t comment just to recommend I stick with a standard input, I’ve already weighed the pros and cons].
When I log the following console.log(Object.entries(e.target));
I get this array:
The second of these items contains my object along with its properties, but I’m wondering why this doesn’t come directly from e.target
. It feels incorrect and risky to access e.target.name
with e.target[1][1].name
.
Relevant code below, starting with the h1
here:
<RecipeName
data-test="recipePage-name"
length={recipe.recipe.name.length}
contentEditable={editable}
onInput={handleChange}
name="name"
value={values.name || recipe.recipe.name}
suppressContentEditableWarning={true}
>
{recipe.recipe.name}
</RecipeName>
And the hook:
const handleChange = e => {
e.persist();
let tmp = { ...values };
let value;
switch (e.target.type) {
case 'number':
value = parseInt(e.target.value);
break;
case 'file':
value = e.target.files[0];
break;
case 'contenteditable':
value = e.target.innerHTML;
break;
default:
value = e.target.value;
}
dot.str(e.target.name, value, tmp);
setValues(tmp);
};
2
Answers
From the docs, Event: type property:
So, in your case, the event listener is added to
onInput
meaning the type of the event isinput
notcontenteditable
. You just need to change thecontenteditable
case toinput
, then it should work.Let’s go with basic JavaScript and demonstrate some issues with the type, value etc. I made lots of comments in the code using
console.log()
to show what is what.I will leave the reactjs conversion exercise to the OP here.