Last active
February 11, 2020 11:14
-
-
Save jul-sh/5ba21f7698aa87ab56081092aef6d3a4 to your computer and use it in GitHub Desktop.
The goal of this hook is to provide an alternative to using indexes as keys in react. Instead, what if we could use the object references as keys. Since React only accepts strings as keys, let's associate string keys to object references.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { render } from 'react-dom' | |
/* | |
The goal of this hook is to provide an alternative to using indexes as | |
keys in react. Instead, what if we could use the object references as keys. | |
Since React only accepts strings as keys, let's associate string keys to | |
object references. | |
*/ | |
function useObjectToKey() { | |
let iterator = 0 | |
const { current: keysByObject } = React.useRef(new WeakMap()) | |
function objectToKey(object) { | |
// If we already genereated a key for this object, | |
// we return it. | |
if (keysByObject.has(object)) { | |
return keysByObject.get(object) | |
} | |
// If we have not stored a string key for this object yet, | |
// we'll create one. | |
const genereatedId = iterator.toString() | |
// And store it, associated to this object | |
keysByObject.set(object, genereatedId) | |
// Lastly we should incement our iterator, so that the | |
// the next generated key is different to the one we just | |
// created. | |
iterator = iterator + 1 | |
// Finally we can return this key | |
return genereatedId | |
} | |
return objectToKey | |
} | |
function GroceryList() { | |
const objectToKey = useObjectToKey() | |
const [groceries, setGroceries] = React.useState([ | |
{ name: 'Soy Milk', quantity: 1 }, | |
{ name: 'Bread', quantity: 2 }, | |
{ name: 'Fruit', quantity: 4 }, | |
{ name: 'N26 Metal Card', quantity: 1 }, | |
{ name: 'Flour', quantity: 2 }, | |
{ name: 'Chocolate', quantity: 2 }, | |
{ name: 'Vegetables', quantity: 3 } | |
]) | |
const removeItem = itemToBeRemoved => { | |
setGroceries(items => items.filter(item => item !== itemToBeRemoved)) | |
} | |
return ( | |
<ul> | |
{groceries.map(item => { | |
const persistentKey = objectToKey(item) | |
return ( | |
<li key={objectToKey(item)}> | |
{item.quantity}x {item.name} | |
<button onClick={() => removeItem(item)}>Remove</button> | |
<small>(persistentKey: {objectToKey(item)})</small> | |
</li> | |
) | |
})} | |
</ul> | |
) | |
} | |
render(<GroceryList />, document.getElementById('root')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment