Goal: I'm trying to create a modal form that opens when clicking an empty div
container, where I can then enter an image URL into a form in the modal. That link will then populate the img tag within the div container.
Problem: After the first keystroke, the modal refreshes, and I have to click into the input filed to continue. I can only enter one letter at a time. I don't think this is an issue that requires e.preventDefault, because this is happening before I hit submit. also I've tried using it as a second argument in my onchange method in the chance that it would work.
The issue only occurs after I set the value of the input field is set to state, and the onChange
event is included.
This is the error that I received in terminal:
findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node
which led me to a question on stack overflow where the scenario was similar, but so far solutions listed haven't worked. But a major take away is that this maybe and issue with changing state causing the modal to re-render. I've began to attempt to implement useRef
, but so far have been unsuccessful.
edit: I realized after looking more into useRef
that my attempt at it was poor, but I was short on time and trying to type this while learning how to use it.
second edit: After reading a bunch that night and the next morning I have found two solutions, useRef
and FormData
, the latter approach I have not been successful with yet, but I believe it to work when used correctly. I've updated my code below to include my progress. I have not yet figured out how to update the dom with hooks.
third edit: I successfully updated the database, but the dom only updates after a refresh. Also, i intended to only update the one div, but I updated all 50. I think this is because of my placement of my form. So, I'm trying to learn how to use forwardRef, and useImparetiveHandle so I can update state where it's being stored in the parent component, and pass multiple refs down.
I think it's also important to note that the breakthrough for me was getting access to the useRef data which I confirmed by adding
alert(imageRef.current.value)
to a handleSubmit method.
Below is a snippet of my code, where different approaches are included the areas that are commented out
///INITIAL APPROACH
const textInput = useRef(null)
const [url, setUrl] = useState("")
const handleChange = (urlData) => {
// e.preventDefault()
// console.log(e.target.value)
// setUrl(prevUrl => prevUrl)
// setUrl(prevUrl => prevUrl + e.target.value)
setUrl(urlData)
// debugger
// setUrl(url + e.target.value)
}
const ModalForm = () => {
return(
<Modal
// animation={false}
show={openModalForm}
onHide={modalToggle}
url={url}
// data-keyboard="false"
data-backdrop="static"
>
<Modal.Header>
<button
className="modalBtn"
onClick={modalToggle}
>X</button>
</Modal.Header>
<form onSubmit={addPhoto} >
<input
ref={textInput}
type="text"
value={url}
// onChange={console.log(url)}
onChange={(e) => {setUrl(e.target.value)}}
// onChange={handleChange}
// onChange={(e) => handleChange(e)}
// onChange={(e) => handleChange(e, e.target.value)}
/>
</form>
<p></p>
</Modal>)}
/// UPDATED APPROACH
const imageRef = useRef()
const detailRef = useRef()
const [url, setUrl] = useState("")
const [details, setDetails] = useState("")
const handleSubmit = (e) => {
e.preventDefault()
console.log(e)
fetch(`http://localhost:3000/photos/${photo.id}`, {
method: 'PATCH',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
image: imageRef.current.value,
details: detailRef.current.value
})
})
.then(res => res.json())
.then(photoObj =>
console.log(photoObj)
// (updatedBox) => {
// setUrl(photo.image)
// setDetails(photo.details)
// }
)
}
<form
ref={form}
onSubmit={handleSubmit}
>
<input
type="text"
name="image"
placeholder="url"
ref={imageRef}
/>
<input
type="text"
name="details"
placeholder="details"
ref={detailRef}
/>
<button type="submit">ENTER</button>
</form>