question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

UPDATE: Some gists with ideas:


React hooks were announced and will be available in React 16.7. I’m opening this issue to talk about a future addition (or maybe an eventual replacement) on Reakit’s API.

My initial idea is to expose hooks instead of components and let the user choose the underlying element in a more straightforward way. The hooks will return objects with html attributes that can be passed direct to elements.

Today:

import { Popover } from "reakit";

const MyPopover = () => (
  <Popover.Container initialState={{ visible: true }}>
    {popover => (
      <Popover.Toggle {...popover}>
        Toggle
        <Popover placement="top" {...popover}>
          <Popover.Arrow />
          Popover
        </Popover>
      </Popover.Toggle>
    )}
  </Popover.Container>
);

Tomorrow:

import { usePopover } from "reakit";

function MyPopover() {
  const { toggle, popover, arrow } = usePopover({ placement: "top", visible: true });
  return (
    <button {...toggle}>
      Toggle
      <div {...popover}>
        <div {...arrow} />
        Popover
      </div>
    </button>
  );
}

The returned object would look like this:

{
  toggle: {
    className: "HiddenToggle-kd7ngs-0",
    onClick: () => toggle(),
    "aria-expanded": false,
    "aria-haspopup": true
  },
  popover: {
    className: "Popover-s6tfv8-0",
    "aria-hidden": true,
    "data-placement": "bottom",
    "role": "group"
  },
  arrow: {
    className: "PopoverArrow-sc-1tkjw1-0",
    children: (
      <svg viewbox="0 0 30 30">
        <path class="stroke"
              d="M23.7,27.1L17,19.9C16.5,19.3,15.8,19,15,19s-1.6,0.3-2.1,0.9l-6.6,7.2C5.3,28.1,3.4,29,2,29h26 C26.7,29,24.6,28.1,23.7,27.1z"
        >
        </path>
        <path class="fill"
              d="M23,27.8c1.1,1.2,3.4,2.2,5,2.2h2H0h2c1.7,0,3.9-1,5-2.2l6.6-7.2c0.7-0.8,2-0.8,2.7,0L23,27.8L23,27.8z"
        >
        </path>
      </svg>
    )
  }
}

The hooks would be decoupled so the users could use their own state handlers with it (just as they can do today by replacing Popover.Container for something else):

import { useState } from "react";
import { usePopover, usePopoverState } from "reakit";

function MyPopover() {
  // const state = usePopoverState({ visible: true });

  const [visible, setVisible] = useState(true);
  const state = {
    visible,
    toggle: () => setVisible(!visible),
    show: () => setVisible(true),
    hide: () => setVisible(false)
  };

  const { toggle, popover, arrow } = usePopover({ placement: "top", ...state });

  return (
    <button {...toggle}>
      Toggle
      <div {...popover}>
        <div {...arrow} />
        Popover
      </div>
    </button>
  );
}

Composing multiple hooks could be as simple as spreading two objects on elements:

<div {...overlay} {...portal} />

But, since they can have conflicting attributes (like both having ref, onClick etc.), we could expose a compose helper that would guarantee that those attributes would be composed, not overwritten.

Today:

import { Overlay, Portal } from "reakit";

const Modal = () => (
  <Overlay.Container>
    {overlay => (
      <Overlay as={Portal} {...overlay}>Overlay</Overlay>
    )}
  </Overlay.Container>
);

Tomorrow:

import { useOverlay, usePortal, compose } from "reakit";

function Modal() {
  const { portal } = usePortal();
  const { overlay } = useOverlay();
  return <div {...compose(portal, overlay)}>Overlay</div>;
}

Well, these are just my initial thoughts, and actually I’m not sure if they make sense, so feedback is really appreciated.

cc @reakit/collaborators

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:13
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
Andaristcommented, Nov 19, 2018

Just my 2 cents - I was experimenting with hooks a little bit, looking also through many implementations in the wild and I came to conclusion that for ref-related hooks it’s best to force people giving a ref to a library. It just seems like it composes best. Example:

function Example() {
  const ref = useRef()
  useOnClickOutside(ref)
  useResizeObserver(ref)
  useSmoothScroller(ref)
  return <div  ref={ref}/>
}
1reaction
Andaristcommented, Nov 20, 2018

No - I’m not aware of any perf-related downsides to your solution (other than the hooks list gets longer with each ref per component, but it’s probably insignificant).

I just think that my proposed way of doing things composes better, because… you dont have to compose in any special way 😅 Just pass an argument and you are ready to go. It also allows passing a ref received from prop directly to the hook, so it just makes more sense to me (also when discussing this on twitter people seemed to lean towards my solution). I agree this looks quite different - because without hooks I probably wouldn’t propose a similar solution, but with hooks it somehow changes my mind about this and after thinking about it a little bit it just seems like a better solution, even if you have to do a little bit of plumbing in your render function.

Read more comments on GitHub >

github_iconTop Results From Across the Web

rfcs/0068-react-hooks.md at main · reactjs/rfcs - GitHub
Summary. In this RFC, we propose introducing Hooks to React. Hooks let you reuse logic between components without changing your component hierarchy.
Read more >
What you need to know about the React useEvent Hook RFC
The useEvent Hook is called with each render of the component where it is used. With each render, the handler function is passed...
Read more >
Make use of `use` in React - a new hook is coming - Vived
The team behind React has unveiled a new hook called `use`. ... Every React RFC (Request For Comments) arouses a lot of interest....
Read more >
All About React's Proposed New use() Hook
RFC : First-class support for Promises. The new feature is all about getting “first-class” support for Promises in React, and is described in...
Read more >
Is the new React use hook a footgun? - YouTube
Code: https://github.com/jherr/use-test RFC : https://github.com/acdlite/ rfcs /blob/.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found