Skip to content

Conversation

@trueadm
Copy link
Contributor

@trueadm trueadm commented Jul 31, 2019

This PR makes some slight adjustments to the exist Flare event system design. After internal testing and from feedback, it was found that passing responders as a React Element to host components, then having detached listeners led to unnecessary boilerplate and some issues around composability. To address these concerns the follow changes have been made:

useListener -> useResponder

There was confusion as to why useListener was actually using an Event Responder, but was named "useListener". Now the hook is useResponder, which takes an Event Responder and returns and Event Listener.

responders prop -> listeners prop

Now that the useResponder hook returns a discrete event listener object, this now gets passed to host components rather than supplying a responder as a React Element on the host component.

To demonstrate these changes, here's a before and after:

// Before
function PressableButton({onPress}) {
  useListener(PressResponder, {onPress});

  return (
    <button responders={<PressResponder />}>Press me</button>
  );
}

// After
function PressableButton({onPress}) {
  const pressListener = useResponder(PressResponder, {onPress});

  return (
    <button listeners={pressListener}>Press me</button>
  );
}

This design change allows us to explore composing the sequence of listeners, allowing for more complex interactions. It also makes the bindings between listeners and their responders more explicit and less magical.

@sizebot
Copy link

sizebot commented Jul 31, 2019

ReactDOM: size: 🔺+0.2%, gzip: 🔺+0.3%

Details of bundled changes.

Comparing: b5af4fe...d3e1b46

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.profiling.min.js -0.2% -0.3% 115.32 KB 115.03 KB 36.3 KB 36.19 KB NODE_PROFILING
react-dom-server.browser.development.js +0.1% +0.1% 136.93 KB 137.04 KB 36.2 KB 36.22 KB UMD_DEV
ReactDOM-dev.js -0.3% -0.3% 932.88 KB 929.88 KB 206.34 KB 205.77 KB FB_WWW_DEV
react-dom-server.browser.production.min.js 🔺+0.2% 🔺+0.3% 19.35 KB 19.39 KB 7.24 KB 7.26 KB UMD_PROD
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.78 KB 3.78 KB 1.52 KB 1.52 KB UMD_DEV
react-dom-test-utils.development.js 0.0% 0.0% 53.99 KB 53.99 KB 14.61 KB 14.62 KB NODE_DEV
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.61 KB 3.61 KB 1.47 KB 1.47 KB NODE_DEV
react-dom-test-utils.production.min.js 0.0% 🔺+0.1% 10.97 KB 10.97 KB 4.04 KB 4.04 KB NODE_PROD
react-dom-unstable-fizz.browser.production.min.js 0.0% -0.2% 1.05 KB 1.05 KB 636 B 635 B NODE_PROD
react-dom.development.js -0.3% -0.2% 909.42 KB 906.48 KB 206.02 KB 205.71 KB UMD_DEV
react-dom.production.min.js -0.2% -0.3% 111.63 KB 111.4 KB 35.89 KB 35.78 KB UMD_PROD
react-dom.profiling.min.js -0.2% -0.1% 115.04 KB 114.81 KB 36.87 KB 36.83 KB UMD_PROFILING
react-dom.development.js -0.3% -0.2% 903.72 KB 900.78 KB 204.54 KB 204.12 KB NODE_DEV
react-dom-server.node.development.js +0.1% +0.1% 134.99 KB 135.1 KB 35.81 KB 35.83 KB NODE_DEV
react-dom.production.min.js -0.3% -0.3% 111.67 KB 111.38 KB 35.34 KB 35.25 KB NODE_PROD
react-dom-server.node.production.min.js 🔺+0.2% 🔺+0.2% 20.13 KB 20.17 KB 7.55 KB 7.56 KB NODE_PROD
ReactDOM-prod.js -0.8% -0.7% 373.44 KB 370.55 KB 68.59 KB 68.12 KB FB_WWW_PROD
ReactDOM-profiling.js -0.8% -0.8% 378.09 KB 375.2 KB 69.66 KB 69.13 KB FB_WWW_PROFILING
react-dom-server.browser.development.js +0.1% +0.1% 133.06 KB 133.17 KB 35.27 KB 35.29 KB NODE_DEV
react-dom-server.browser.production.min.js 🔺+0.2% 🔺+0.2% 19.28 KB 19.32 KB 7.25 KB 7.26 KB NODE_PROD
ReactDOMServer-dev.js +0.1% +0.1% 135.09 KB 135.2 KB 34.65 KB 34.68 KB FB_WWW_DEV
ReactDOMServer-prod.js 🔺+0.2% 🔺+0.2% 46.3 KB 46.38 KB 10.72 KB 10.75 KB FB_WWW_PROD
react-dom-unstable-fizz.node.development.js 0.0% +0.1% 3.85 KB 3.85 KB 1.5 KB 1.5 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 10.48 KB 10.48 KB 3.58 KB 3.58 KB NODE_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js -0.2% -0.1% 645.06 KB 643.83 KB 140.7 KB 140.56 KB UMD_DEV
react-art.production.min.js -0.3% -0.4% 102.59 KB 102.3 KB 31.32 KB 31.21 KB UMD_PROD
react-art.development.js -0.2% -0.1% 575.94 KB 574.7 KB 123.4 KB 123.25 KB NODE_DEV
react-art.production.min.js -0.4% -0.5% 67.63 KB 67.34 KB 20.63 KB 20.53 KB NODE_PROD
ReactART-dev.js -0.2% -0.1% 589.87 KB 588.65 KB 122.97 KB 122.83 KB FB_WWW_DEV
ReactART-prod.js -0.5% -0.6% 221.15 KB 219.98 KB 37.72 KB 37.5 KB FB_WWW_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-prod.js -0.3% -0.4% 272.65 KB 271.97 KB 46.82 KB 46.65 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js -0.2% -0.3% 281.07 KB 280.39 KB 48.34 KB 48.18 KB RN_OSS_PROFILING
ReactFabric-prod.js -0.3% -0.4% 266.33 KB 265.65 KB 45.86 KB 45.69 KB RN_OSS_PROD
ReactFabric-profiling.js -0.3% -0.3% 275 KB 274.31 KB 47.31 KB 47.16 KB RN_OSS_PROFILING
ReactFabric-dev.js -0.4% -0.3% 736.6 KB 733.51 KB 155.69 KB 155.18 KB RN_FB_DEV
ReactFabric-prod.js -0.3% -0.4% 266.34 KB 265.65 KB 45.87 KB 45.71 KB RN_FB_PROD
ReactNativeRenderer-dev.js -0.2% -0.1% 723.89 KB 722.67 KB 153.24 KB 153.1 KB RN_OSS_DEV
ReactFabric-profiling.js -0.3% -0.3% 275 KB 274.31 KB 47.32 KB 47.16 KB RN_FB_PROFILING
ReactNativeRenderer-dev.js -0.2% -0.1% 723.98 KB 722.76 KB 153.28 KB 153.15 KB RN_FB_DEV
ReactNativeRenderer-prod.js -0.3% -0.4% 272.65 KB 271.96 KB 46.82 KB 46.66 KB RN_FB_PROD
ReactNativeRenderer-profiling.js -0.2% -0.3% 281.06 KB 280.38 KB 48.35 KB 48.19 KB RN_FB_PROFILING
ReactFabric-dev.js -0.4% -0.3% 736.5 KB 733.41 KB 155.64 KB 155.14 KB RN_OSS_DEV

react-events

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-events-swipe.development.js +6.8% +3.3% 6.17 KB 6.59 KB 1.69 KB 1.75 KB UMD_DEV
react-events-keyboard.development.js +5.5% +3.3% 4.11 KB 4.33 KB 1.59 KB 1.64 KB UMD_DEV
ReactEventsPress-dev.js +2.2% +1.4% 21.74 KB 22.22 KB 5.08 KB 5.15 KB FB_WWW_DEV
react-events-swipe.production.min.js 🔺+2.1% 🔺+1.3% 2.57 KB 2.63 KB 1.17 KB 1.19 KB UMD_PROD
ReactEventsDrag-dev.js +12.2% +6.5% 5.16 KB 5.79 KB 1.48 KB 1.58 KB FB_WWW_DEV
react-events-keyboard.production.min.js 🔺+3.6% 🔺+1.1% 1.81 KB 1.88 KB 1021 B 1.01 KB UMD_PROD
react-events-hover.development.js +6.3% +5.0% 6.37 KB 6.77 KB 1.62 KB 1.7 KB UMD_DEV
react-events-input.development.js +5.3% +3.7% 4.31 KB 4.54 KB 1.38 KB 1.43 KB UMD_DEV
react-events-hover.production.min.js 🔺+3.9% 🔺+5.2% 2.92 KB 3.04 KB 1.15 KB 1.21 KB UMD_PROD
ReactEventsFocus-dev.js +8.1% +6.5% 9.27 KB 10.02 KB 1.99 KB 2.12 KB FB_WWW_DEV
react-events-input.production.min.js 🔺+4.0% 🔺+2.0% 1.75 KB 1.82 KB 952 B 971 B UMD_PROD
ReactEventsScroll-dev.js +6.8% +4.0% 5.49 KB 5.86 KB 1.5 KB 1.56 KB FB_WWW_DEV
ReactEventsFocus-prod.js 🔺+8.6% 🔺+9.5% 7.25 KB 7.88 KB 1.48 KB 1.63 KB FB_WWW_PROD
ReactEventsScroll-prod.js 🔺+3.8% 🔺+4.7% 4.32 KB 4.48 KB 1.27 KB 1.33 KB FB_WWW_PROD
react-events-hover.development.js +6.5% +5.5% 6.19 KB 6.59 KB 1.57 KB 1.66 KB NODE_DEV
react-events-input.development.js +5.5% +4.3% 4.13 KB 4.35 KB 1.33 KB 1.38 KB NODE_DEV
react-events-hover.production.min.js 🔺+4.3% 🔺+6.4% 2.74 KB 2.86 KB 1.08 KB 1.14 KB NODE_PROD
react-events-input.production.min.js 🔺+4.5% 🔺+2.7% 1.58 KB 1.65 KB 882 B 906 B NODE_PROD
react-events-press.development.js +2.2% +1.6% 21.23 KB 21.69 KB 4.96 KB 5.04 KB UMD_DEV
react-events-drag.development.js +11.7% +5.6% 5.32 KB 5.94 KB 1.58 KB 1.67 KB UMD_DEV
react-events-press.production.min.js 🔺+0.2% 🔺+0.1% 7.08 KB 7.09 KB 2.68 KB 2.69 KB UMD_PROD
ReactEventsHover-dev.js +7.1% +6.2% 6.22 KB 6.66 KB 1.58 KB 1.68 KB FB_WWW_DEV
react-events-drag.production.min.js 🔺+4.1% 🔺+3.6% 2.38 KB 2.48 KB 1.1 KB 1.14 KB UMD_PROD
ReactEventsInput-dev.js +5.4% +4.3% 4.2 KB 4.43 KB 1.33 KB 1.38 KB FB_WWW_DEV
ReactEventsHover-prod.js 🔺+9.9% 🔺+7.0% 5.28 KB 5.8 KB 1.4 KB 1.49 KB FB_WWW_PROD
ReactEventsInput-prod.js 🔺+5.3% 🔺+3.1% 3.04 KB 3.2 KB 1.11 KB 1.14 KB FB_WWW_PROD
react-events-press.development.js +2.2% +1.7% 21.05 KB 21.5 KB 4.91 KB 4.99 KB NODE_DEV
react-events-drag.development.js +8.8% +4.3% 7.08 KB 7.7 KB 2.24 KB 2.33 KB NODE_DEV
react-events-press.production.min.js 🔺+0.2% 🔺+0.1% 6.9 KB 6.91 KB 2.62 KB 2.63 KB NODE_PROD
react-events-drag.production.min.js 🔺+3.3% 🔺+3.0% 3.02 KB 3.12 KB 1.41 KB 1.45 KB NODE_PROD
ReactEventsPress-prod.js 🔺+0.8% 🔺+0.7% 16.71 KB 16.84 KB 3.61 KB 3.64 KB FB_WWW_PROD
ReactEventsDrag-prod.js 🔺+10.0% 🔺+7.0% 3.96 KB 4.35 KB 1.22 KB 1.3 KB FB_WWW_PROD
react-events-swipe.development.js +7.0% +3.6% 5.99 KB 6.41 KB 1.65 KB 1.71 KB NODE_DEV
react-events-keyboard.development.js +5.8% +3.8% 3.92 KB 4.15 KB 1.54 KB 1.59 KB NODE_DEV
react-events-swipe.production.min.js 🔺+2.3% 🔺+1.4% 2.39 KB 2.45 KB 1.12 KB 1.13 KB NODE_PROD
react-events-keyboard.production.min.js 🔺+4.0% 🔺+1.6% 1.63 KB 1.7 KB 946 B 961 B NODE_PROD
react-events-focus.development.js +7.6% +5.3% 9.45 KB 10.16 KB 2.01 KB 2.12 KB UMD_DEV
react-events-scroll.development.js +6.7% +3.9% 5.57 KB 5.94 KB 1.53 KB 1.58 KB UMD_DEV
react-events-focus.production.min.js 🔺+6.4% 🔺+6.9% 3.71 KB 3.94 KB 1.24 KB 1.32 KB UMD_PROD
ReactEventsSwipe-dev.js +7.1% +3.8% 6.15 KB 6.59 KB 1.66 KB 1.73 KB FB_WWW_DEV
react-events-scroll.production.min.js 🔺+3.6% 🔺+3.1% 2.3 KB 2.39 KB 1.06 KB 1.09 KB UMD_PROD
ReactEventsKeyboard-dev.js +6.3% +3.9% 3.98 KB 4.22 KB 1.52 KB 1.58 KB FB_WWW_DEV
ReactEventsSwipe-prod.js 🔺+1.3% 🔺+1.7% 5.13 KB 5.2 KB 1.44 KB 1.46 KB FB_WWW_PROD
ReactEventsKeyboard-prod.js 🔺+5.9% 🔺+1.5% 3.09 KB 3.27 KB 1.14 KB 1.15 KB FB_WWW_PROD
react-events-focus.development.js +7.8% +5.7% 9.26 KB 9.98 KB 1.96 KB 2.07 KB NODE_DEV
react-events-scroll.development.js +6.9% +4.8% 5.38 KB 5.75 KB 1.47 KB 1.54 KB NODE_DEV
react-events-focus.production.min.js 🔺+6.7% 🔺+7.4% 3.53 KB 3.77 KB 1.17 KB 1.26 KB NODE_PROD
react-events-scroll.production.min.js 🔺+3.9% 🔺+4.0% 2.11 KB 2.2 KB 1000 B 1.02 KB NODE_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactTestRenderer-dev.js -0.2% -0.1% 600.85 KB 599.62 KB 125.43 KB 125.29 KB FB_WWW_DEV
react-test-renderer-shallow.development.js +0.4% +0.3% 39.37 KB 39.51 KB 9.92 KB 9.95 KB UMD_DEV
react-test-renderer-shallow.production.min.js 🔺+0.4% 🔺+0.2% 11.62 KB 11.66 KB 3.55 KB 3.55 KB UMD_PROD
react-test-renderer-shallow.development.js +0.4% +0.3% 33.5 KB 33.64 KB 8.51 KB 8.53 KB NODE_DEV
react-test-renderer-shallow.production.min.js 🔺+0.3% 🔺+0.4% 11.77 KB 11.81 KB 3.67 KB 3.68 KB NODE_PROD
react-test-renderer.development.js -0.2% -0.1% 588.85 KB 587.61 KB 125.99 KB 125.84 KB UMD_DEV
react-test-renderer.production.min.js -0.4% -0.4% 69.14 KB 68.85 KB 21.14 KB 21.05 KB UMD_PROD
ReactShallowRenderer-dev.js +0.4% +0.3% 33.49 KB 33.63 KB 8.36 KB 8.38 KB FB_WWW_DEV
react-test-renderer.development.js -0.2% -0.1% 584.4 KB 583.15 KB 124.87 KB 124.72 KB NODE_DEV
react-test-renderer.production.min.js -0.4% -0.4% 68.88 KB 68.59 KB 20.93 KB 20.84 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js -0.2% -0.1% 574.02 KB 572.79 KB 121.97 KB 121.81 KB NODE_DEV
react-reconciler.production.min.js -0.4% -0.5% 68.85 KB 68.56 KB 20.47 KB 20.37 KB NODE_PROD
react-reconciler-reflection.development.js 0.0% 0.0% 16.63 KB 16.63 KB 5.16 KB 5.16 KB NODE_DEV
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.59 KB 2.59 KB 1.14 KB 1.14 KB NODE_PROD
react-reconciler-persistent.development.js -0.2% -0.1% 571.03 KB 569.8 KB 120.7 KB 120.55 KB NODE_DEV
react-reconciler-persistent.production.min.js -0.4% -0.5% 68.86 KB 68.58 KB 20.47 KB 20.38 KB NODE_PROD

Generated by 🚫 dangerJS

@trueadm trueadm force-pushed the further-flare-design-tweaks branch 2 times, most recently from e8866b0 to 8ede067 Compare July 31, 2019 11:59
@trueadm trueadm force-pushed the further-flare-design-tweaks branch from 8ede067 to 55ee752 Compare July 31, 2019 12:23
@necolas
Copy link
Contributor

necolas commented Jul 31, 2019

Thanks this looks good! The implementation appears simpler too. I do have a few questions / comments.

context.dispatchEvent

The implementation is still dispatching named events. Why do we need to do this? What is the payload type needed for now? And if it's necessary to treat the gesture lifecycle as a series of events internally, is that something we can better hide from the responder callbacks (i.e., not having the event type in the payload they receive)? In Flutter this object is called "details", in SwiftUI this is object is called "GestureState". That's how we're using it too – an object the reflects the current gesture state.

Responder propagation control

We've discussed several ownership models but this wasn't one of them. I'm not sure refs are a practical way to negotiate ownership as the same ref would have to be passed around a lot. I don't think the term "propagation" is relevant in the context of ownership over a pointer / gesture. We should chat about this idea at work.

Remove FocusScope

👍 But let's do this as a separate PR.

@trueadm
Copy link
Contributor Author

trueadm commented Jul 31, 2019

@necolas

The implementation is still dispatching named events

I didn't want to change the event object shapes as part of this PR.

We've discussed several ownership models but this wasn't one of them.

This isn't to do with the ownership model. It's just a way of allowing responders of the same type to not propagate. Without this our internal Pressability design will no longer work.

But let's do this as a separate PR.

I wanted to avoid converting the FocusScope module and tests over. I guess I can do that though.

@necolas
Copy link
Contributor

necolas commented Jul 31, 2019

I didn't want to change the event object shapes as part of this PR.

That makes perfect sense. But beyond this PR that's something I'd like to better understand. Something we can chat about in person.

This isn't to do with the ownership model

I think this is still part of the system that determines which responders should be active, like the behavior concept. Should we keep the existing mechanism for now and revisit it in another PR after this gets merged?

I wanted to avoid converting the FocusScope module and tests over.

No need to do that. We can merge a PR that removes FocusScope before this one gets applied to master.

@trueadm
Copy link
Contributor Author

trueadm commented Jul 31, 2019

That makes perfect sense. But beyond this PR that's something I'd like to better understand. Something we can chat about in person.

Agreed. I thought this might be an area that you'd like to spend some time working on actually, but you'd want the design changes in before you did that.

I think this is still part of the system that determines which responders should be active, like the behavior concept. Should we keep the existing mechanism for now and revisit it in another PR after this gets merged?

Agreed that it doesn't make much sense now. I'll remove that logic and the code for it. As long as we don't sync, this should be fine anyway.

I've also put up a PR for the removal of FocusScope #16267 and I've updated the summary of this PR.

@trueadm
Copy link
Contributor Author

trueadm commented Aug 1, 2019

I've restored the old logic for how responder propagation occurs.

@trueadm trueadm merged commit 4279455 into facebook:master Aug 1, 2019
@trueadm trueadm deleted the further-flare-design-tweaks branch August 1, 2019 18:08
NMinhNguyen referenced this pull request in enzymejs/react-shallow-renderer Jan 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants