Saher Elgendy
Saher Elgendy

Reputation: 1619

Why id and itemId never match in that react code?

This is a simple representation of my real problem in a project, it seems i am missing something in react or may be the problem is not related to react, this is my code https://codesandbox.io/s/lucid-northcutt-c3fw4?file=/src/App.js

i need to show the item on the list when click on it, and this never happens because that condition never get true and i don't know why?

{id === itemId && el}

Upvotes: 0

Views: 1142

Answers (4)

Ashik Paul
Ashik Paul

Reputation: 504

I'm assuming v4 generates a random ID. So id === itemId will never be true.

And I don't see itemId being initialized anywhere.

It would be great if you can tell me what is that condition for?

Or try {id === itemId || item}

Hope this helps Thank you

Upvotes: 0

Vivek Doshi
Vivek Doshi

Reputation: 58593

Issue :

id={v4()} this will create a new uuid on each render, so when you click handleItemClick it update itemId and which cause re-render and all ids got changed due to id={v4()} so this will never get true {id === itemId && item}

{arr.map(el => {
    return <Item
        id={v4()} // <------ Issue is hear
        itemId={itemId}
        item={el}
        handleItemClick={handleItemClick} 
    />;
})}

Solution :

// instead of creating uuid on render you can create and save it as state, so it won't change on each re-render
const [items, setItems] = useState([1, 2, 3, 4].map(() => v4()));

{items.map(id => {
    return (
    <Item
        id={id} // <----- Then use it like this
        itemId={itemId}
        item={id}
        handleItemClick={handleItemClick}
    />
    );
})}

WORKING DEMO :

Edit #SO-solved-v4()

Upvotes: 2

Santosh
Santosh

Reputation: 126

First you missed the key prop, when using map(). It will just throw the warning, not to worry about much :P.

the main problem in your code is, v4 will generate random keys on each render. so the id will never be the same as itemId. try to use some static id. if you can like the map comes with index. you may use that

arr.map((el,index) => {
return <Item
           id={index}
           key={el}
           itemId={itemId}
           item={el}
           handleItemClick={handleItemClick} 
        />;
});

Upvotes: 0

David
David

Reputation: 219027

When you click the element, you successfully set the itemId value to the id of the clicked element:

const handleItemClick = id => {
    setItemId(id);
};

However, upon re-rendering the component you dynamically generate all new id values:

id={v4()}

It's highly unlikely (re: impossible) that the newly generated UUID will be the same as the previously generated one.

Don't generate new UUID id values on every render. Either use static values or perhaps just an incrementing value from .map():

{arr.map((el, i) => {
    return <Item
        id={i}
        itemId={itemId}
        item={el}
        handleItemClick={handleItemClick} 
     />;
 ))}

Upvotes: 2

Related Questions