I was getting this warning:
react-dom.development.js:86 Warning: Invalid value for prop
reset
on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://reactjs.org/link/attribute-behavior
This came from my custom hook:
import { useState } from 'react'
export const useField = (type) => {
const [value, setValue] = useState('')
const onChange = (event) => {
setValue(event.target.value)
}
const reset = () => {
setValue('')
}
return {
type,
value,
onChange,
reset
}
}
The hook is used in a component:
const CreateNew = (props) => {
const content = useField('text')
const author = useField('text')
const info = useField('text')
const navigate = useNavigate()
const handleSubmit = (e) => {
e.preventDefault()
props.addNew({
content: content.value,
author: author.value,
info: info.value,
votes: 0
})
navigate('/')
props.setNotification(`a new anecdote ${content.value} created!`)
setTimeout(() => {
props.setNotification(null)
}, 5000)
}
const handleReset = (event) => {
console.log(content)
content.onReset()
author.onReset()
info.onReset()
}
return (
<div>
<h2>create a new anecdote</h2>
<form onSubmit={handleSubmit}>
<div>
content
<input {...content} />
</div>
<div>
author
<input {...author} />
</div>
<div>
url for more info
<input {...info} />
</div>
<button type="submit">create</button>
<button type="button" onClick={handleReset}>reset</button>
</form>
</div>
)
}
The warning disappeared when I change the name of the function reset
to onReset
, but I don't understand why.
Is onReset
a special keyword for react or something? I changed it on pure luck and the problem was gone but I don't get why.
You are passing a reset
prop/attribute to an input
element that is an invalid attribute value, it's a function, not a string or a number.
const useField = (type) => {
const [value, setValue] = useState("");
const onChange = (event) => {
setValue(event.target.value);
};
const reset = () => {
setValue("");
};
return {
type,
value, // <-- is a function
onChange,
reset
};
};
...
const content = useField('text'); // <-- includes reset function
...
<input {...content} /> // <-- reset spread to input, causes error
See input tag for a list of valid attributes.
The reason React doesn't flag the name onReset
is because this is a valid event handler (but for form
elements, not input
), see Synthetic Events.
Is onReset a special keyword for react or something? I changed it on pure luck and the problem was gone but I don't get why.
If you follow the link in the warning, buried in the page is this note.
Note: attributes starting with on are not passed through as an exception because this could become a potential security hole.
Additionally there's an issue in the handleReset
callback that is referencing undefined properties and attempting to invoke them, which will obviously throw an error when the preceding issues are resolved.
const handleReset = (event) => {
console.log(content);
content.onReset(); // <-- onReset is undefined, should call content.reset()
author.onReset();
info.onReset();
};
Destructure the reset
function from the useField
hook's return value and spread the rest into a props object. Reference the correct reset function in handleReset
.
Example:
const CreateNew = (props) => {
const { reset: resetContent, ...content } = useField("text");
const { reset: resetAuthor, ...author } = useField("text");
const { reset: resetInfo, ...info } = useField("text");
...
const handleReset = (event) => {
console.log(content);
resetContent();
resetAuthor();
resetInfo();
};
return (
<div>
<h2>create a new anecdote</h2>
<form onSubmit={handleSubmit}>
<div>
content
<input {...content} />
</div>
<div>
author
<input {...author} />
</div>
<div>
url for more info
<input {...info} />
</div>
<button type="submit">create</button>
<button type="button" onClick={handleReset}>
reset
</button>
</form>
</div>
);
};