0

Here I map though an array of objects that contain images to display on a page. At the moment when I try useRef it only grabs me the very last element. How can I have it so that my useRef grabs me multiple?

  <div className='images-container'>
             {skills.map((skill, idx) => {
                    return <div key={idx}>
                        <img alt={skill.name} ref={imageRef} src={skill.url} />
                        <p>{skill.name}</p>
                    </div>
                })}
            </div>

If I am understanding correctly use ref will only grab one of these elements so I suppose the best approach is to dynamically make different useRefs to grab individually? Sorry, just learning react.

  • Why do you need the DOM elements at all, instead of... you know... working with the actual data that generates those elements? – Mike 'Pomax' Kamermans Jan 09 '22 at 23:37
  • I need to grab the dom elements because the html canvas method drawImage() requires a reference to an image tag as the first parameter – Marcos Saucedo Jan 10 '22 at 02:32
  • 1
    sure, but the canvas does not require the images to be _in the DOM_. So, since the browser has those images cached now, you can also just map your state variable to new image objects for use with the canvas. E.g. `skills.forEach(s => { const im = new Image(); im.src=s.url; ctx.drawImage(im, ...); })` – Mike 'Pomax' Kamermans Jan 10 '22 at 16:50

1 Answers1

0

Best solution: don't use refs you probably don't need them. If you tell us why you think you need refs we can verify if you're right.

Second best, create an array of refs of the same length as your skills list. A ref can only point to one object. What you're doing is placing the same refs on many objects which isn't how refs are designed to work.

const refs = [];
for (let i = 0; i < skills.length; i++) {
    refs.push(useRef());
}
return (
  <div className='images-container'>
             {skills.map((skill, idx) => {
                    return <div key={idx}>
                        <img alt={skill.name} ref={refs[idx]} src={skill.url} />
                        <p>{skill.name}</p>
                    </div>
                })}
            </div>
)

nlta
  • 1,716
  • 1
  • 7
  • 17
  • Ahh sorry, the reason I think I need useRef is because I am grabbing that element to use the draw image method that canvas offers. I am trying to display all the images that ive mapped and in order to do that I need to grab an element by its ref – Marcos Saucedo Jan 10 '22 at 01:53
  • Okay access to dom apis **is** a case where you'll need to use ref. Please accept the answer if your problem is solved. – nlta Jan 10 '22 at 02:58