I am using React JS and I have a text field which is supposed to change its content as the user clicks on different UI components. I also want to be able to edit the text in that text field (and later I would like to send that text to the UI component, but that is another story). So far I got this code
import React, { useContext } from 'react'
import './ContextualMenu.css'
import { EditorContext } from '../../EditorBase'
const ContextualMenu = props => {
const editorContext = useContext(EditorContext)
const handleUpdates = (event) => {
console.log(event.target.value)
}
const displayNodeAttr = () => {
return (
<>
<div className="menu-title">{editorContext.selectedNode.nodeType}</div>
<div>
<div className="menu-item">
<div className="menu-item-label">Name</div>
<div className="menu-item-value">
<input
className="menu-item-input"
type="text"
value={editorContext.selectedNode.nodeAttr.name}
onChange={handleUpdates}
/>
</div>
</div>
</div>
</>
)
}
return (
<div id="c-contextual-menu">
{editorContext.selectedNode.nodeAttr && displayNodeAttr()}
</div>
)
}
export default ContextualMenu
This makes the text always return to the original text that was set when the user clicked on the component. If i replace line 21 (value={editorContext.selectedNode.nodeAttr.name}) with placeholder={editorContext.selectedNode.nodeAttr.name} then the hint always shows the correct text as the user click on UI components but it shows it as a hint and i would like to have it as text.
It seems to me that the input text field detects a change (has a listener on the change event or something like that) and it immediately reverts the text to the original text, which makes it basically uneditable. Any ideas?
Update: After the answers by @alireza and @Juviro I changed the code due to the fact that initially the selected node is null and as the user selects the node then it becomes not null. So the code now looks like this (it is just the relevant part):
const ContextualMenu = props => {
const editorContext = useContext(EditorContext)
const val = editorContext.selectedNode && editorContext.selectedNode.nodeAttr ? editorContext.selectedNode.nodeAttr.name : ''
const [value, setValue] = useState(val)
const handleUpdates = (event) => {
setValue(event.target.value)
console.log(event.target.value)
}
const displayNodeAttr = () => {
return (
<>
<div className="menu-title">{editorContext.selectedNode.nodeType}</div>
<div>
<div className="menu-item">
<div className="menu-item-label">Name</div>
<div className="menu-item-value">
<input
className="menu-item-input"
type="text"
value={value}
onChange={handleUpdates}
/>
</div>
</div>
</div>
</>
)
}
return (
<div id="c-contextual-menu">
{editorContext.selectedNode.nodeAttr && displayNodeAttr()}
</div>
)
}
The problem now is that the input field is never set to any value when the user clicks on the UI components (nodes). It is as if the value is set on page load and then never updated as the user selects components (nodes). If now I use val instead of value like this: value={val} then the input field is updated correctly but then i get back to the old problem of not being able to edit its content.
valueproperty of the input component.valueprop to an input component you are setting it as a controlled component, meaning that you need to handle passing down the changed value after onChange event is triggered.