https://github.com/uvacoder/use-descendants-hook
https://github.com/uvacoder/use-descendants-hook
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/uvacoder/use-descendants-hook
- Owner: Uvacoder
- Created: 2022-09-16T01:43:44.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2022-09-16T01:43:55.000Z (over 3 years ago)
- Last Synced: 2025-01-24T06:08:36.100Z (about 1 year ago)
- Language: JavaScript
- Size: 104 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# useDescendants 
> This is the README for beta releases. The "stable" (but still v0) release is here: https://github.com/pacocoursey/use-descendants/tree/v0
useDescendants is a react hook for keeping track of descendant components and their relative indeces. It's based off the [@reach/descendants](https://www.npmjs.com/package/@reach/descendants) package, but faster and smaller.
If you want to understand more about what this package does or why we need it, read the [Problem Complex](https://www.npmjs.com/package/@reach/descendants) from the @reach/descendants package.
In short, this package allows each item in a list to know it's relative index and the parent of the list can keep track of each child, without needing to render in a loop and pass each component an index.
This enables component composition:
```js
{/* I'm index 0 */}
{/* I'm index 1 */}
{/* I'm arbitrarily nested, but still know that I'm index 2 */}
```
## Installation
```
$ yarn add use-descendants@beta
```
## Usage
In the parent, you call `useDescendants` and pass the result to `` that wraps the children. In each child item, retrieve that items index with the `useDescendant` hook.
```jsx
const Menu = () => {
const context = useDescendants()
return (
)
}
const Item = () => {
const index = useDescendant()
return
My index is {index}
}
```
#### React.memo
Items that use `React.memo` or stable keys will still have an up-to-date index, as they will be forcefully re-rendered whenever the parent re-renders. This means you can safely remove `React.memo`, as it will always be bypassed.
#### Data passing
You can pass any data you want to `useDescendant` and it will be available in the parent through `map`:
```jsx
// In Item
const ref = useRef()
const index = useDescendant({ ref })
// In Menu
const context = useDescendants()
console.log(context.map.current)
// => { '': { index: 0, props: { ref: HTMLDivElement } } }
```
You can also pass un-memoized values or callbacks that are always up-to-date here because it's just kept in a ref:
```jsx
const index = useDescendant({
onSelect: () => {
/* Do something */
}
})
```
## Credits
- [@reach/descendants](https://www.npmjs.com/package/@reach/descendants) and [Chance](https://twitter.com/chancethedev), who introduced me to this concept
- [Shu Ding](https://twitter.com/shuding_) for help with a faster, simpler implementation