Search code examples
javascriptreactjs

React UI not updating when React a property of React object state changes


I have a component that uses an object as the state. The object is passed in as a prop. The problem is, I have an input field where there is a cancel button. When the user clicks on the cancel button, I discard all the handleChange events which is saved on the local component state, then just reuse the original prop that was passed in. The text in the input field however, does not reset to the original value and keeps the value that was with the change event.

// Prop structure myObjProp
{id: '', inputText: 'Original String Val'}

const MyComponent = ({myObjProp}) => {
  const [objState, setObjState] = useState({...myObjProp})
  const {id, inputText} = objState

  const handleChange = (e) => setObjState({...objState, inputText: e.target.value})
   
  const handleCancel = () => setObjState(myObjProp) // Should reset `inputText` back to `Original String Val`
  

  return (
    <div>
      <input onChange={handleChange} />
      <button onClick={handleCancel} defaultValue={inputText} >Cancel</button>
    </div>
  )
}

As an example, when the component first loads, the text in the input will be Original String Val. When I then start typing and the input value is something like Original String Val Changed, after I click the Cancel button, the text in the input should be Original String Val which is the original value from the prop and I set in the cancel handler, but text does not revert back and stays as the new text I just typed Original String Val Changed


Solution

  • Essentially, you're not controlling the input. In order to so you'll want to add a value tag.

     <div>
       <input onChange={handleChange} value={inputText} />
       <button onClick={handleCancel} defaultValue={inputText}>
           Cancel
       </button>
    </div>
    

    This will also put in 'Original String Val' as the text when the user opens the page. If you want to limit that, you'll need to create another state just for the value.