Skip to content

Commit

Permalink
rename descendants init hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Chance Strickland committed May 14, 2020
1 parent 9cf605e commit 52d721c
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 15 deletions.
6 changes: 4 additions & 2 deletions packages/accordion/src/index.tsx
Expand Up @@ -35,7 +35,7 @@ import {
DescendantProvider,
useDescendant,
useDescendantKeyDown,
useDescendants,
useDescendantsInit,
} from "@reach/descendants";
import { useId } from "@reach/auto-id";
import PropTypes from "prop-types";
Expand Down Expand Up @@ -90,7 +90,9 @@ export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
const wasControlled = typeof controlledIndex !== "undefined";
const { current: isControlled } = useRef(wasControlled);

const [descendants, setDescendants] = useDescendants<AccordionDescendant>();
const [descendants, setDescendants] = useDescendantsInit<
AccordionDescendant
>();

const id = useId(props.id);

Expand Down
5 changes: 3 additions & 2 deletions packages/combobox/src/index.tsx
Expand Up @@ -48,6 +48,7 @@ import {
DescendantProvider,
useDescendant,
useDescendants,
useDescendantsInit,
} from "@reach/descendants";
import { findAll } from "highlight-words-core";
import { useId } from "@reach/auto-id";
Expand Down Expand Up @@ -279,7 +280,7 @@ export const Combobox = forwardRefWithAs<ComboboxProps, "div">(
},
forwardedRef
) {
let [options, setOptions] = useDescendants<ComboboxDescendant>();
let [options, setOptions] = useDescendantsInit<ComboboxDescendant>();

// Need this to focus it
const inputRef = useRef();
Expand Down Expand Up @@ -963,7 +964,7 @@ function useKeyDown() {
persistSelectionRef,
} = useContext(ComboboxContext);

const { descendants: options } = useContext(ComboboxDescendantContext);
const options = useDescendants(ComboboxDescendantContext);

return function handleKeyDown(event: React.KeyboardEvent) {
let index = options.findIndex(({ value }) => value === navigationValue);
Expand Down
8 changes: 7 additions & 1 deletion packages/descendants/README.md
Expand Up @@ -260,7 +260,7 @@ function Menu({ id, children }) {
// but you may want to do something with `descendants` in your top-level
// component and we don't want to force creating an arbitrary child
// component just so we can consume the context.
let [descendants, setDescendants] = useDescendants();
let [descendants, setDescendants] = useDescendantsInit();
let [activeIndex, setActiveIndex] = useState(-1);
return (
<DescendantProvider
Expand Down Expand Up @@ -335,6 +335,12 @@ function MenuItem({ index: explicitIndex, ...props }) {
}
```

You can also access the descendants object anywhere in the tree (below the top-level component) with `useDescendants`:

```jsx
let menuItems = useDescendants(DescendantContext);
```

The key tradeoff here is that descendants won't be available on the first render, and as such any components that need this data for server-side rendering will need to manage their own state and pass descendant data from from the top of the tree. For example

```jsx
Expand Down
8 changes: 7 additions & 1 deletion packages/descendants/src/index.tsx
Expand Up @@ -66,10 +66,16 @@ export function useDescendant<DescendantType extends Descendant>(
);
}

export function useDescendants<DescendantType extends Descendant>() {
export function useDescendantsInit<DescendantType extends Descendant>() {
return useState<DescendantType[]>([]);
}

export function useDescendants<DescendantType extends Descendant>(
ctx: React.Context<DescendantContextValue<DescendantType>>
) {
return React.useContext(ctx).descendants;
}

export function DescendantProvider<DescendantType extends Descendant>({
context: Ctx,
children,
Expand Down
6 changes: 3 additions & 3 deletions packages/listbox/src/index.tsx
Expand Up @@ -45,6 +45,7 @@ import {
useDescendant,
useDescendantKeyDown,
useDescendants,
useDescendantsInit,
} from "@reach/descendants";
import {
createNamedContext,
Expand Down Expand Up @@ -121,7 +122,7 @@ export const ListboxInput = forwardRef<
forwardedRef
) {
let isControlled = useRef(valueProp != null);
let [options, setOptions] = useDescendants<ListboxDescendant>();
let [options, setOptions] = useDescendantsInit<ListboxDescendant>();

let onChange = useCallbackProp(onChangeProp);

Expand Down Expand Up @@ -1270,8 +1271,7 @@ function useKeyDown() {
stateData: { navigationValue, typeaheadQuery },
send,
} = useContext(ListboxContext);

let { descendants: options } = useContext(ListboxDescendantContext);
let options = useDescendants(ListboxDescendantContext);

useEffect(() => {
if (typeaheadQuery) {
Expand Down
7 changes: 5 additions & 2 deletions packages/menu-button/src/index.tsx
Expand Up @@ -30,6 +30,7 @@ import {
DescendantProvider,
useDescendant,
useDescendants,
useDescendantsInit,
useDescendantKeyDown,
} from "@reach/descendants";
import {
Expand Down Expand Up @@ -98,7 +99,9 @@ export const Menu: React.FC<MenuProps> = ({ id, children }) => {
let buttonRef = useRef(null);
let menuRef = useRef(null);
let popoverRef = useRef(null);
let [descendants, setDescendants] = useDescendants<MenuButtonDescendant>();
let [descendants, setDescendants] = useDescendantsInit<
MenuButtonDescendant
>();
let [state, dispatch] = useReducer(reducer, initialState);
let _id = useId(id);
let menuId = id || makeId("menu", _id);
Expand Down Expand Up @@ -545,7 +548,7 @@ export const MenuItems = forwardRefWithAs<MenuItemsProps, "div">(
selectCallbacks,
state: { isExpanded, buttonId, selectionIndex, typeaheadQuery },
} = useContext(MenuContext);
const { descendants: menuItems } = useContext(MenuDescendantContext);
const menuItems = useDescendants(MenuDescendantContext);
const ref = useForkedRef(menuRef, forwardedRef);

useEffect(() => {
Expand Down
8 changes: 4 additions & 4 deletions packages/tabs/src/index.tsx
Expand Up @@ -32,6 +32,7 @@ import {
DescendantProvider,
useDescendant,
useDescendantKeyDown,
useDescendantsInit,
useDescendants,
} from "@reach/descendants";
import {
Expand Down Expand Up @@ -121,7 +122,7 @@ export const Tabs = forwardRefWithAs<TabsProps, "div">(function Tabs(

let [focusedIndex, setFocusedIndex] = useState(-1);

let [tabs, setTabs] = useDescendants<TabDescendant>();
let [tabs, setTabs] = useDescendantsInit<TabDescendant>();

let context: InternalTabsContextValue = useMemo(() => {
return {
Expand Down Expand Up @@ -315,8 +316,7 @@ const TabListImpl = forwardRefWithAs<TabListProps, "div">(function TabList(
selectedIndex,
setSelectedIndex,
} = useContext(TabsContext);

let { descendants: tabs } = useContext(TabsDescendantsContext);
let tabs = useDescendants(TabsDescendantsContext);

let ownRef = useRef<HTMLElement | null>(null);
let ref = useForkedRef(forwardedRef, ownRef);
Expand Down Expand Up @@ -561,7 +561,7 @@ const TabPanelsImpl = forwardRefWithAs<TabPanelsProps, "div">(
function TabPanels({ children, as: Comp = "div", ...props }, forwardedRef) {
let ownRef = useRef();
let ref = useForkedRef(ownRef, forwardedRef);
let [tabPanels, setTabPanels] = useDescendants<TabPanelDescendant>();
let [tabPanels, setTabPanels] = useDescendantsInit<TabPanelDescendant>();

return (
<DescendantProvider
Expand Down

0 comments on commit 52d721c

Please sign in to comment.