0

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>
  • Why do we use `url` as a prop to `Modal` component? Whenever you type in the input box, the `url` gets changed, and `Modal` component re-renders because of one of its props is changed. – Adel Tahir Jul 02 '21 at 02:01
  • the ```modal``` re-renders without ```url``` passed as a prop, but you make a good point. I was just trying whatever I could think of. – Corey Colligan Jul 02 '21 at 14:12

1 Answers1

2

I'm a little late, but I resolved the re-rendering issue by moving the modal from within the function and into the components return

  • Can confirm this works, however I have no clue why? Can anyone elaborate this? – Bram Hammer Jun 24 '22 at 22:39
  • Hi there, A year too late but I have the same issue. So do I have to put my modals into the return of the whole component??? God, this will ruin my code. Any other solution found? Cheers! :) – Tony Feb 15 '23 at 21:46