WDI-SEA / project-4-issues

Open an issue to receive help on project 4 issues
0 stars 0 forks source link

Array in state populates by replacing most recently added, in most cases #20

Closed dinosaur96m closed 2 years ago

dinosaur96m commented 2 years ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

MERN konva framework for canvas

What's the problem you're trying to solve?

I am holding an array of canvas-populated images (each a component, per konva docs) in state. Only sometimes does clicking a thumbnail add an additional image to the array, otherwise it just replaces the most recently populated image.

Post any code you think might be relevant (one fenced block per file)

Editor.js

// function: Thumbnail->onClick: paintImage on Canvas
    const paintImage = (obj) => {
        console.log("obj: ", obj)
        // map e.target onto CanvasImage.js
        // push new Canvas Image into state
        // TO DO: debug: new images replaces most recent 
            //unless a category button is pressed in betwenn
        let newArray = [...canvasImages, <CanvasImage url={obj.image} height={obj.dimensions[0]} width={obj.dimensions[1]}/>]
        setCanvasImages(newArray)
    }

Thumbnail.js

 return (
        <div>
            <img style={{height: 80}} src={props.item.image} onClick={() => props.paintImage(props.item)}></img>
        </div>

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

I render my thumbnails by category, so below a list buttons named after each room category ('kitchen" etc.). Only after I press one of these buttons does clicking a thumbnail add a new image to the array instead of replacing the most recent.

What is your best guess as to the source of the problem?

I'm guessing this is a React lifecycle issue. Lifting state seems to be the go to solution for lifecycle issues, but the state holding the array canvasImages, and the function populating the array paintImage() are in the "Editor.js" component which is the grandparent of "Thumbnail.js" and the parent of "CanvasImage.js"

What things have you already tried to solve the problem?

Iterations of paintImage():

using the spread syntax in one line:

        setCanvasImages([...canvasImages, <CanvasImage url={obj.image} height={obj.dimensions[0]} width={obj.dimensions[1]}/>])

saving the the array from state in a variable, then pushing the new image:

    let newArray = canvasImages
    newArray.push(<CanvasImage url={obj.image} height={obj.dimensions[0]} width={obj.dimensions[1]}/>)
        setCanvasImages(newArray)
I also switched the onClick in Thumbnail.js to an anonymous callback function
dinosaur96m commented 2 years ago

Met with Timm, going to try refactoring to store an array objects instead of components in the array. Found a stack overflow post that said storing components in state is 'decidedly' bad practice 😳

dinosaur96m commented 2 years ago

Populating the array with objects didn't fix the issue with updating state, I'm not even able to get the Image components to render, but if I could that wouldn't fix the state issue

dinosaur96m commented 2 years ago

Was still holding components in state in Thumbnail.js πŸ˜… Using forEach instead of map in Editor.js made the konva image components render the objects which are now held in state 'canvasImages'! πŸ‘