I'm modifying some existing code in React, and I'm running into unexpected behavior with dynamic buttons within a form.
There is a button that is rendered dynamically based on the state, isEditing
.
- When
isEditing
is false, the button will render "Edit", and it has anonClick
callback that will update the state to true. - When
isEditing
is true, the button will render "Done" and instead of anonClick
callback, it will have the propertytype=submit
. In this case, clicking the button will trigger theonSubmit
callback of the form that contains it. The form'sonSubmit
callback will update theisEditing
state back to false.
The existing code has these different versions of the button set up with the conditional &&
operator, and it works as expected in toggling the state with each click.
However, when I tried to recreate the same setup with a ternary instead of the &&
, the behavior is broken. When isEditing
is false, clicking the button will trigger the onClick
callback as expected, but then it immediately triggers the onSubmit
callback of the form as well.
The compiled output of both of these appear like they should be identical, but for whatever reason they are behaving differently. I'm wondering what is causing this difference in behavior. Why is the ternary version submitting the form while the &&
version isn't?
Here is a code snippet with the relevant parts along with a link to a codepen where I recreated the issue. State updates are handled with React Hooks. Thanks
const App = () => {
const [isEditing, setIsEditing] = useState(false)
const handleSubmit = event => {
event.preventDefault()
setIsEditing(false)
}
const handleClick = () => {
setIsEditing(true)
}
return (
<>
<form onSubmit={handleSubmit}>
{/* WORKING */}
{isEditing && (
<button type="submit">Working Done</button>
)}
{!isEditing && (
<button onClick={handleClick}>Working Edit</button>
)}
{/* NOT WORKING */}
{isEditing ? (
<button type="submit">Broken Done</button>
) : (
<button onClick={handleClick}>Broken Edit</button>
)}
</form>
</>
)
}