profile
viewpoint
Sunil Pai threepointone Bangalore, India

emotion-js/emotion 10455

👩‍🎤 CSS-in-JS library designed for high performance style composition

threepointone/css-suspense 312

css loading for react

TheLarkInn/unity-component-specification 209

This is a WIP draft of the Unity (Single File Web Component) Specification

threepointone/bs-nice 187

css-in-reason

threepointone/babel-macros 10

macros for babel. I think.

threepointone/asyncstorage-mock 9

a mock for react-native's asyncstorage api. useful for testing.

threepointone/css-in-js-workshop 6

css, in your js, in your head, in your heart

paramaggarwal/Rubber 2

iOS apps in Javascript like React Native.

threepointone/bus 2

global event bus

threepointone/async-act-test-21-11 1

Created with CodeSandbox

pull request commentreactjs/react-codemod

Allow transformer parameters to be provided via cli

why is it important that the command accept these parameters via cli?

c-cal

comment created time in 11 hours

push eventreactjs/reactjs.org

Sunil Pai

commit sha 562bf36aedd91b4c57675d3b5d10084212033458

Remove Sunil from team page (#2887) Removes Sunil from the team, and move to acknowledgements. I also moved Sasha so it's sorted correctly

view details

push time in 3 days

PR merged reactjs/reactjs.org

Remove Sunil from team page CLA Signed react core team

Removes Sunil from the team, and move to acknowledgements. I also moved Sasha so it's sorted correctly.

+2 -9

1 comment

1 changed file

threepointone

pr closed time in 3 days

PR opened reactjs/reactjs.org

Remove Sunil from team page

Removes Sunil from the team, and move to acknowledgements. I also moved Sasha so it's sorted correctly.

+2 -9

0 comment

1 changed file

pr created time in 3 days

create barnchreactjs/reactjs.org

branch : threepointone-sunil-remove

created branch time in 3 days

issue closedfacebook/react

Bug:

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. -->

React version:

Steps To Reproduce

<!-- Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Issues without reproduction steps or code examples may be immediately closed as not actionable. -->

Link to code example:

<!-- Please provide a CodeSandbox (https://codesandbox.io/s/new), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve. -->

The current behavior

The expected behavior

closed time in 8 days

dwpk

Pull request review commentfacebook/react

Refactor Enter/Leave listener accumulation

 const eventTypes = { // Start of inline: the below functions were inlined from // EventPropagator.js, as they deviated from ReactDOM's newer // implementations.++function getParent(inst) {

I get that this is 'legacy', but it's weird that fibers are called instances here (since we use that word for something else elsewhere.

could you explain why this other traversal fns are inlined multiple times instead of in one module? Also why do some of them have types, and some don't?

trueadm

comment created time in 8 days

pull request commentfacebook/react

Move accumulateEventTargetListeners to its own module/function

boo codesandbox boo

trueadm

comment created time in 9 days

issue commentfacebook/react

Bug: NotFoundError: Node was not found

It's not clear without a small reproduction on either codesandbox, or as a git repo, what the issue actually is. Please share a reproducible example.

Please also test by disabling browser extensions, as React doesn't behave well with extensions that change the dom invasively.

krishnaTORQUE

comment created time in 13 days

issue closedfacebook/react

Having errors with usereducer and usecallback functions

const formReducer=(state, action) => {
    switch (action.type) {
        case 'INPUT_CHANGE':
            let formIsValid = true;
            for (const inputId in state.inputs) {
                if (inputId === action.inputId) {
                    formIsValid = formIsValid && action.isValid;
                } else {
                    formIsValid = formIsValid && state.inputs[inputId].isValid;
                }
            }
          return {
              ...state,
              inputs:{
                  ...state.inputs,
                  [action.inputId]:{value: action.value, isValid: action.isValid}
              },
              isValid: formIsValid
          };
        default:
            return state;
    }
};

const newplace =() => {
   const[formState,dispatch] =  useReducer(formReducer, {
        inputs:{
            title:{
                value:'',
                isValid: false
            },
            description:{
                value:'',
                isValid: false
            }
        },
        isValid: false
    });
    const InputHandler = useCallback((id, value, isValid) => {
        dispatch({type: 'INPUT_CHANGE', value: value, isValid: isValid, inputId: id });
         
    },[]);

closed time in 13 days

Ncjustus123

issue commentfacebook/react

Having errors with usereducer and usecallback functions

@devanfarrell is right, the linter recognises components based on its name, which should be capitalised. Closing this issue, thanks!

Ncjustus123

comment created time in 13 days

delete branch threepointone/react-native-website

delete branch : og-image

delete time in 14 days

pull request commentfacebook/react-native-website

adds og:image to every page

So it looks like older pages may still be cached with twitter, and may or may not be refresh in the near future. Some rarer pages already show the image correctly tho. eg: In this image - image the first is a link to https://reactnative.dev/ and you can see there isn't an image, and the second to https://reactnative.dev/docs/platform-specific-code, which has the correct image. I'm assuming the older ones will fix themselves as the caches flush.

threepointone

comment created time in 14 days

pull request commentfacebook/react-native-website

adds og:image to every page

Yeah I dunno how to do it per page, eg- in the react docs we’d override react helmet something or the other. In any case it would be a future PR, this should be good for now.

threepointone

comment created time in 14 days

PR opened facebook/react-native-website

adds og:image to every page

This PR adds an og:image meta tag to every page, and reuses react's og:image for the same. This means links shared on twitter will correctly have a react logo as an attached image.

I can't verify that this actually works till the PR lands, but the generated html looked fine to me. image

+2 -0

0 comment

2 changed files

pr created time in 14 days

create barnchthreepointone/react-native-website

branch : og-image

created branch time in 14 days

Pull request review commentfacebook/react

ReactDOM.useEvent: Add support for experimental scopes API

 export default function accumulateTwoPhaseListeners(             dispatchInstances.push(node);           }         }+      } else if (enableScopeAPI && node.tag === ScopeComponent) {

I'm assuming this logic is from flare's implementation?

trueadm

comment created time in 15 days

create barnchreactjs/reactjs.org

branch : threepointone-remove-sunil

created branch time in 16 days

issue closedfacebook/react

Bug: Best practice - React.createElement children argument to be always array.

Maintain consistency

When a parent component contains children, sometimes it is passed as an object and sometimes it is passed as an array.

Example: <Parent> <Child></Child> </Parent>

In the above example, typeof Parent.children will be object whereas

<Parent> <Child></Child> <Child></Child> </Parent>

typeof Parent.children will be Array.

The current behavior

Single child is treated as object and List of child is treated as array.

The expected behavior

Single child and list to be treated as an array of children.

Example

https://codesandbox.io/s/mystifying-antonelli-j4qe3

closed time in 20 days

imvetri

issue commentfacebook/react

Bug: Best practice - React.createElement children argument to be always array.

It’s an internal implementation detail that shouldn’t be relevant to anyone else. Among other things, it prevents extra allocations when not needed. Closing this, thanks for the concern!

imvetri

comment created time in 20 days

issue commentfacebook/react

Bug: Best practice - React.createElement children argument to be always array.

Why does this matter? It’s not meant to be manipulated/introspected by an app developer anyway, and if they do need to, there are React.Children helpers to do so.

This isn’t a bug.

imvetri

comment created time in 20 days

pull request commentfacebook/react

ReactDOM.useEvent: add `EventTarget` support

This seems to include changes from the last PR. Rebase please?

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 import type {EventPriority} from 'shared/ReactTypes'; import type {TopLevelType} from './TopLevelEventTypes';  export type DispatchConfig = {|-  dependencies: Array<TopLevelType>,-  phasedRegistrationNames?: {|-    bubbled: string,-    captured: string,+  dependencies?: Array<TopLevelType>,+  phasedRegistrationNames: {|+    bubbled: null | string,+    captured: null | string,   |},   registrationName?: string,   eventPriority: EventPriority, |}; +export type CustomDispatchConfig = {|+  phasedRegistrationNames: {|+    bubbled: null,+    captured: null,+  |},+  customEvent?: boolean,

won't this always be true?

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 describe('DOMModernPluginEventSystem', () => {             dispatchClickEvent(button);             expect(clickEvent).toHaveBeenCalledTimes(1);           });++          it('handle propagation of custom user events', () => {+            const buttonRef = React.createRef();+            const divRef = React.createRef();+            const log = [];+            const onCustomEvent = jest.fn(e =>+              log.push(['bubble', e.currentTarget]),+            );+            const onCustomEventCapture = jest.fn(e =>+              log.push(['capture', e.currentTarget]),+            );++            function Test() {+              let custom;++              // Test that we get a warning when we don't provide an explicit priortiy+              expect(() => {+                custom = ReactDOM.unstable_useEvent('custom-event');+              }).toWarnDev(+                'Warning: The event "type" provided to useEvent() does not have a known priority type. ' ++                  'It is recommended to provide a "priority" option to specify a priority.',+              );++              custom = ReactDOM.unstable_useEvent('custom-event', {+                priority: 0, // Discrete+              });++              const customCapture = ReactDOM.unstable_useEvent('custom-event', {

same here

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 describe('DOMModernPluginEventSystem', () => {             dispatchClickEvent(button);             expect(clickEvent).toHaveBeenCalledTimes(1);           });++          it('handle propagation of custom user events', () => {+            const buttonRef = React.createRef();+            const divRef = React.createRef();+            const log = [];+            const onCustomEvent = jest.fn(e =>+              log.push(['bubble', e.currentTarget]),+            );+            const onCustomEventCapture = jest.fn(e =>+              log.push(['capture', e.currentTarget]),+            );++            function Test() {+              let custom;
              let customEventHandle;

maybe not 'Handle', but I do think this should be a descriptive name

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 describe('DOMModernPluginEventSystem', () => {             dispatchClickEvent(button);             expect(clickEvent).toHaveBeenCalledTimes(1);           });++          it('handle propagation of custom user events', () => {+            const buttonRef = React.createRef();+            const divRef = React.createRef();+            const log = [];+            const onCustomEvent = jest.fn(e =>+              log.push(['bubble', e.currentTarget]),+            );+            const onCustomEventCapture = jest.fn(e =>+              log.push(['capture', e.currentTarget]),+            );++            function Test() {+              let custom;++              // Test that we get a warning when we don't provide an explicit priortiy+              expect(() => {+                custom = ReactDOM.unstable_useEvent('custom-event');+              }).toWarnDev(+                'Warning: The event "type" provided to useEvent() does not have a known priority type. ' ++                  'It is recommended to provide a "priority" option to specify a priority.',

I know this is old, but it's only obvious to me now that this isn't clear. What are the possible values of priority? Where can I learn more about it? etc. In a future PR this message should be made verbose, especially if we expect people to start using custom events.

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 export function attachElementListener(listener: ReactDOMListener): void {     listeners = new Set();     initListenersSet(target, listeners);   }-  // Finally, add our listener to the listeners Set.+  // Add our listener to the listeners Set.   listeners.add(listener);+  // Finally, add the event to our known event types list.+  let dispatchConfig = topLevelEventsToDispatchConfig.get(type);+  // If we don't have a dispatchConfig, then we're dealing with+  // an event type that React does not know about (i.e. a custom event).+  // We need to register an event config for this or the SimpleEventPlugin+  // will not appropiately provide a SyntheticEvent, so we use out empty
  // will not appropriately provide a SyntheticEvent, so we use an empty
trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 import type {EventPriority} from 'shared/ReactTypes'; import type {TopLevelType} from './TopLevelEventTypes';  export type DispatchConfig = {|-  dependencies: Array<TopLevelType>,-  phasedRegistrationNames?: {|-    bubbled: string,-    captured: string,+  dependencies?: Array<TopLevelType>,+  phasedRegistrationNames: {|+    bubbled: null | string,+    captured: null | string,   |},   registrationName?: string,-  eventPriority: EventPriority,+  eventPriority?: EventPriority,+  customEvent?: boolean, |};

I recommend instead splitting this as two types, something like

export type DispatchConfig = {|
  dependencies: Array<TopLevelType>,
  phasedRegistrationNames?: {|
    bubbled: string,
    captured: string,
  |},
  registrationName?: string,
  eventPriority: EventPriority,
  customEvent: false
|} | {|
  phasedRegistrationNames: {|
    bubbled: null,
    captured: null,
  |},
  customEvent: true
|};

ie - one for regular, and one for custom events. this way you won't accidentally mix fields if you mean differently.

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 describe('DOMModernPluginEventSystem', () => {             dispatchClickEvent(button);             expect(clickEvent).toHaveBeenCalledTimes(1);           });++          it('handle propagation of custom user events', () => {
          it('handles propagation of custom user events', () => {
trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 const SimpleEventPlugin: PluginModule<MouseEvent> = {         break;       default:         if (__DEV__) {-          if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {+          if (+            knownHTMLTopLevelTypes.indexOf(topLevelType) === -1 &&

this could be a Set but ehhh nevermind

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

ReactDOM.useEvent: support custom types

 export default function accumulateTwoPhaseListeners(           }         }       }-      // Standard React on* listeners, i.e. onClick prop-      const captureListener = getListener(node, captured);-      if (captureListener != null) {-        // Capture listeners/instances should go at the start, so we-        // unshift them to the start of the array.-        dispatchListeners.unshift(captureListener);-        dispatchInstances.unshift(node);+      //

stray comment

trueadm

comment created time in 21 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function listenToEvent(   } } -const validFBLegacyPrimerRels = new Set([-  'dialog',-  'dialog-post',-  'async',-  'async-post',-  'theater',-  'toggle',-]);--function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {-  let node = nativeEvent.target;-  const type = nativeEvent.type;-  if (type !== 'click') {+function willDeferLaterForLegacyFBSupport(+  topLevelType: DOMTopLevelEventType,+  targetContainer: EventTarget,+): boolean {+  if (topLevelType !== TOP_CLICK) {     return false;   }-  while (node !== null) {-    // Primer works by intercepting a click event on an <a> element-    // that has a "rel" attribute that matches one of the valid ones-    // in the Set above. If we intercept this before Primer does, we-    // will need to defer the current event till later and discontinue-    // execution of the current event. To do this we can add a document-    // event listener and continue again later after propagation.-    if (node.tagName === 'A' && validFBLegacyPrimerRels.has(node.rel)) {-      const legacyFBSupport = true;-      const isCapture = nativeEvent.eventPhase === 1;-      addTrappedEventListener(-        null,-        ((type: any): DOMTopLevelEventType),-        isCapture,-        legacyFBSupport,-      );-      return true;-    }-    node = node.parentNode;-  }-  return false;+  // We defer all click events with legacy FB support mode on.+  // This means we add a one time event listener to trigger+  // after the FB delegated listeners fire.+  const legacyFBSupport = true;
  const isDeferredListenerForLegacyFBSupport = true;
trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function listenToEvent(   } } -const validFBLegacyPrimerRels = new Set([-  'dialog',-  'dialog-post',-  'async',-  'async-post',-  'theater',-  'toggle',-]);--function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {-  let node = nativeEvent.target;-  const type = nativeEvent.type;-  if (type !== 'click') {+function willDeferLaterForLegacyFBSupport(+  topLevelType: DOMTopLevelEventType,+  targetContainer: EventTarget,+): boolean {+  if (topLevelType !== TOP_CLICK) {     return false;   }-  while (node !== null) {-    // Primer works by intercepting a click event on an <a> element-    // that has a "rel" attribute that matches one of the valid ones-    // in the Set above. If we intercept this before Primer does, we-    // will need to defer the current event till later and discontinue-    // execution of the current event. To do this we can add a document-    // event listener and continue again later after propagation.-    if (node.tagName === 'A' && validFBLegacyPrimerRels.has(node.rel)) {-      const legacyFBSupport = true;-      const isCapture = nativeEvent.eventPhase === 1;-      addTrappedEventListener(-        null,-        ((type: any): DOMTopLevelEventType),-        isCapture,-        legacyFBSupport,-      );-      return true;-    }-    node = node.parentNode;-  }-  return false;+  // We defer all click events with legacy FB support mode on.+  // This means we add a one time event listener to trigger+  // after the FB delegated listeners fire.+  const legacyFBSupport = true;+  addTrappedEventListener(+    targetContainer,+    topLevelType,+    false,+    legacyFBSupport,
    isDeferredListenerForLegacyFBSupport,
trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function dispatchEventForPluginEventSystem(       // TODO: useEvent for document and window       return;     }-    // If we detect the FB legacy primer system, we+    // If we are using the legacy FB support flag, we     // defer the event to the null with a one     // time event listener so we can defer the event.     if (-      enableLegacyFBPrimerSupport &&-      willDeferLaterForFBLegacyPrimer(nativeEvent)+      enableLegacyFBSupport &&+      (eventSystemFlags & LEGACY_FB_SUPPORT) === 0 &&

Oh ok I get it. I think the structure of the comment confused me - "if we are using legacy, then we defer event", and I didn't notice willDeferLaterForLegacyFBSupport is a boolean returning function, I though it was inside the block ha.

trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function addTrappedEventListener(   if (passive === true && !passiveBrowserEventsSupported) {     passive = false;   }+  const eventSystemFlags =+    enableLegacyFBSupport && legacyFBSupport

this is a bit confusing because you'd imagine legacyFBSupport would always be true if enableLegacyFBSupport is true. I think it means this is a badly named argument. Something to consider for a future PR?

trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function listenToEvent(   } } -const validFBLegacyPrimerRels = new Set([-  'dialog',-  'dialog-post',-  'async',-  'async-post',-  'theater',-  'toggle',-]);--function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {-  let node = nativeEvent.target;-  const type = nativeEvent.type;-  if (type !== 'click') {+function willDeferLaterForLegacyFBSupport(+  topLevelType: DOMTopLevelEventType,+  targetContainer: EventTarget,+): boolean {+  if ((topLevelType: any) !== 'click') {

maybe 'click'should be the one that's coerced to DOMTopLevelEventType instead?

(I'm honestly not sure, feel free to correct me)

trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function addTrappedEventListener(     targetContainer = document;   } -  const validTargetContainer = ((targetContainer: any): EventTarget);+  const targetContainerToUse =

I don't think this rename is meaningfully different, but ok. Maybe just reassign on targetContainer?

trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function dispatchEventForPluginEventSystem(       // TODO: useEvent for document and window       return;     }-    // If we detect the FB legacy primer system, we+    // If we are using the legacy FB support flag, we     // defer the event to the null with a one     // time event listener so we can defer the event.     if (-      enableLegacyFBPrimerSupport &&-      willDeferLaterForFBLegacyPrimer(nativeEvent)+      enableLegacyFBSupport &&+      (eventSystemFlags & LEGACY_FB_SUPPORT) === 0 &&

This condition would mean the LEGACY_FB_SUPPORT bit is not set. Did you mean

      (eventSystemFlags & LEGACY_FB_SUPPORT) !== 0 &&
trueadm

comment created time in 22 days

Pull request review commentfacebook/react

Modern Event System: refactor legacy FB support logic

 export function listenToEvent(   } } -const validFBLegacyPrimerRels = new Set([-  'dialog',-  'dialog-post',-  'async',-  'async-post',-  'theater',-  'toggle',-]);--function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {-  let node = nativeEvent.target;-  const type = nativeEvent.type;-  if (type !== 'click') {+function willDeferLaterForLegacyFBSupport(+  topLevelType: DOMTopLevelEventType,+  targetContainer: EventTarget,+): boolean {+  if ((topLevelType: any) !== 'click') {

why is this type coerced? it's (opaquely) defined as a string, so shouldn't this comparison just work?

trueadm

comment created time in 22 days

push eventreactjs/reactjs.org

Fran Zekan

commit sha 84acbe1b8a0306041a195eba95be6221564c1f92

Fix node version in readme (#2837)

view details

push time in 22 days

PR merged reactjs/reactjs.org

Fix node version in readme CLA Signed

I forgot to change the Node version in README when upgrading to Node 12 in #2831 , so here is the fix

+1 -1

5 comments

1 changed file

Zeko369

pr closed time in 22 days

pull request commentreactjs/reactjs.org

Fix node version in readme

Thank you!

Zeko369

comment created time in 22 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      Scheduler.unstable_flushAll();++      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(2);++      // Clicking the button should also work+      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(log[2]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: buttonRef.current,+      });++      function Test2({clickEvent2}) {+        const click = ReactDOM.unstable_useEvent('click', clickEvent2);++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent2);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      let clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);++      // Reset the function we pass in, so it's different+      clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);+    });++    it('should correctly work for setting and clearing a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test({off}) {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        React.useEffect(() => {+          if (off) {+            click.setListener(buttonRef.current, null);+          }+        }, [off]);++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test off={false} />, container);+      Scheduler.unstable_flushAll();++      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // The listener should get unmounted in the second effect+      ReactDOM.render(<Test off={true} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);

this is confusing because the intent is to say that clickEvent wasn't called, but in isolation this line looks like it was called. clear clickEvent before this section?

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      Scheduler.unstable_flushAll();++      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();+

clear log here?

log = []
trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      Scheduler.unstable_flushAll();++      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(2);++      // Clicking the button should also work+      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(log[2]).toEqual({

so you can assert on log's shape again here

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      Scheduler.unstable_flushAll();++      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(2);++      // Clicking the button should also work+      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(log[2]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: buttonRef.current,+      });++      function Test2({clickEvent2}) {+        const click = ReactDOM.unstable_useEvent('click', clickEvent2);++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent2);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      let clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);++      // Reset the function we pass in, so it's different+      clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);+    });++    it('should correctly work for setting and clearing a basic "click" listener', () => {+      const log = [];

there are no assertions on log in this test, so maybe remove it?

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 function dispatchAction<S, A>(  const noOpMount = () => {}; +function validateNotInFunctionRender(): boolean {+  if (currentlyRenderingFiber === null) {+    return true;+  }+  if (__DEV__) {+    console.warn(+      'Event listener methods from useEvent() cannot be used during render.' +
      'Event listener methods from useEvent() cannot be called during render.' +
trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 function dispatchAction<S, A>(  const noOpMount = () => {}; +function validateNotInFunctionRender(): boolean {+  if (currentlyRenderingFiber === null) {+    return true;+  }+  if (__DEV__) {+    console.warn(+      'Event listener methods from useEvent() cannot be used during render.' +

I think this message can be improved, but ok to do so for a future PR.

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      Scheduler.unstable_flushAll();++      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(2);++      // Clicking the button should also work+      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(log[2]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: buttonRef.current,+      });++      function Test2({clickEvent2}) {+        const click = ReactDOM.unstable_useEvent('click', clickEvent2);++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent2);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      let clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);++      // Reset the function we pass in, so it's different+      clickEvent2 = jest.fn();+      ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent2).toBeCalledTimes(1);+    });++    it('should correctly work for setting and clearing a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test({off}) {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        React.useEffect(() => {+          if (off) {+            click.setListener(buttonRef.current, null);+          }+        }, [off]);++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test off={false} />, container);+      Scheduler.unstable_flushAll();++      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // The listener should get unmounted in the second effect+      ReactDOM.render(<Test off={true} />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);+    });++    it('handle propagation of click events', () => {+      const buttonRef = React.createRef();+      const divRef = React.createRef();+      const log = [];+      const onClick = jest.fn(e => log.push(['bubble', e.currentTarget]));+      const onClickCapture = jest.fn(e =>+        log.push(['capture', e.currentTarget]),+      );++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');+        const clickCapture = ReactDOM.unstable_useEvent('click', {+          capture: true,+        });++        React.useEffect(() => {+          click.setListener(buttonRef.current, onClick);+          clickCapture.setListener(buttonRef.current, onClickCapture);+          click.setListener(divRef.current, onClick);+          clickCapture.setListener(divRef.current, onClickCapture);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(onClick).toHaveBeenCalledTimes(1);+      expect(onClickCapture).toHaveBeenCalledTimes(1);+      expect(log[0]).toEqual(['capture', buttonElement]);+      expect(log[1]).toEqual(['bubble', buttonElement]);++      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(onClick).toHaveBeenCalledTimes(3);+      expect(onClickCapture).toHaveBeenCalledTimes(3);+      expect(log[2]).toEqual(['capture', buttonElement]);+      expect(log[3]).toEqual(['capture', divElement]);+      expect(log[4]).toEqual(['bubble', divElement]);+      expect(log[5]).toEqual(['bubble', buttonElement]);+    });++    it('should correctly work for a basic "click" listener on the outer target', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: divRef.current,+        target: divRef.current,+      });++      // Unmounting the container and clicking should not work+      ReactDOM.render(null, container);+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(1);++      // Re-rendering the container and clicking should work+      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(clickEvent).toBeCalledTimes(2);++      // Clicking the button should not work+      let buttonElement = buttonRef.current;+      dispatchClickEvent(buttonElement);+      expect(clickEvent).toBeCalledTimes(2);+    });++    it('should correctly handle many nested target listeners', () => {+      const buttonRef = React.createRef();+      const targetListerner1 = jest.fn();
      const targetListener1 = jest.fn();

(and the ones after this one too)

trueadm

comment created time in 24 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 export default function accumulateTwoPhaseListeners(   while (node !== null) {     // We only care for listeners that are on HostComponents (i.e. <div>)     if (node.tag === HostComponent) {+      // For useEvent listenrs+      if (enableUseEventAPI && accumulateUseEventListeners) {+        // useEvent event listeners+        const instance = node.stateNode;+        const targetType = event.type;+        const listeners = getListenersFromTarget(instance);++        if (listeners !== null) {+          const listenersArr = Array.from(listeners);+          for (let i = 0; i < listenersArr.length; i++) {+            const listener = listenersArr[i];+            const {+              callback,+              event: {capture, type},+            } = listener;+            if (type === targetType) {+              if (capture) {
              if (capture === true) {

(not sure if this nullable, hence the nit)

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });

this way you can assert on log's length too

      expect(log).toEqual([{
        eventPhase: 3,
        type: 'click',
        currentTarget: buttonRef.current,
        target: divRef.current,
      }]);
trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 export function beforeRemoveInstance(   ) {     dispatchBeforeDetachedBlur(((instance: any): HTMLElement));   }+  if (enableUseEventAPI) {+    // It's unfortunate that we have to do this cleanup, but+    // it's necessary otherwise we will leak the host instances+    // from the useEvent hook instances Map. We call destroy+    // on each listener to ensure we properly remove the instance+    // from the instances Map. Note: we have this Map so that we+    // can properly unmount instances when the function component+    // that the hook is attached to gets unmounted.+    const listenersSet = getListenersFromTarget(instance);+    if (listenersSet !== null) {+      const listeners = Array.from(listenersSet);

only because I'm nitpicking - what is your opinion on using Set's forEach here?

trueadm

comment created time in 25 days

Pull request review commentfacebook/react

ReactDOM.useEvent: wire to event system to the hook

 describe('DOMModernPluginEventSystem', () => {       expect(listenerMaps.length).toEqual(2);       expect(listenerMaps[0]).toEqual(listenerMaps[1]);     });++    it('can render correctly with the ReactDOMServer', () => {+      const clickEvent = jest.fn();++      function Test() {+        const divRef = React.useRef(null);+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(divRef.current, clickEvent);+        });++        return <div ref={divRef}>Hello world</div>;+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(`<div data-reactroot="">Hello world</div>`);+    });++    it('can render correctly with the ReactDOMServer hydration', () => {+      const clickEvent = jest.fn();+      const spanRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(spanRef.current, clickEvent);+        });++        return (+          <div>+            <span ref={spanRef}>Hello world</span>+          </div>+        );+      }+      const output = ReactDOMServer.renderToString(<Test />);+      expect(output).toBe(+        `<div data-reactroot=""><span>Hello world</span></div>`,+      );+      container.innerHTML = output;+      ReactDOM.hydrate(<Test />, container);+      Scheduler.unstable_flushAll();+      dispatchClickEvent(spanRef.current);+      expect(clickEvent).toHaveBeenCalledTimes(1);+    });++    it('should correctly work for a basic "click" listener', () => {+      const log = [];+      const clickEvent = jest.fn(event => {+        log.push({+          eventPhase: event.eventPhase,+          type: event.type,+          currentTarget: event.currentTarget,+          target: event.target,+        });+      });+      const divRef = React.createRef();+      const buttonRef = React.createRef();++      function Test() {+        const click = ReactDOM.unstable_useEvent('click');++        React.useEffect(() => {+          click.setListener(buttonRef.current, clickEvent);+        });++        return (+          <button ref={buttonRef}>+            <div ref={divRef}>Click me!</div>+          </button>+        );+      }++      ReactDOM.render(<Test />, container);+      Scheduler.unstable_flushAll();++      expect(container.innerHTML).toBe('<button><div>Click me!</div></button>');++      // Clicking the button should trigger the event callback+      let divElement = divRef.current;+      dispatchClickEvent(divElement);+      expect(log[0]).toEqual({+        eventPhase: 3,+        type: 'click',+        currentTarget: buttonRef.current,+        target: divRef.current,+      });+
expect(clickEvent).toBeCalledTimes(1);

count once before the next step

trueadm

comment created time in 25 days

pull request commentreactjs/reactjs.org

WIP: add missing documentation URLs to /versions

They’re not the deploy preview URLs (check the bottom half of versions.yml, they don’t have ‘deploy preview’ in them). Bugging Brian for netlify access, will continue next week.

threepointone

comment created time in a month

issue commenttesting-library/react-testing-library

9.3.1 requires MessageChannel implementation

Should probably file a new issue since it’s not the same thing

eps1lon

comment created time in a month

issue commenttesting-library/react-testing-library

9.3.1 requires MessageChannel implementation

Oh hmm I dunno what the esm implications are. I’ll think about it.

eps1lon

comment created time in a month

PR closed reactjs/reactjs.org

Update introducing-jsx.md CLA Signed

The img element does not need a closing tag.

<!--

Thank you for the PR! Contributors like you keep React awesome!

Please see the Contribution Guide for guidelines:

https://github.com/reactjs/reactjs.org/blob/master/CONTRIBUTING.md

If your PR references an existing issue, please add the issue number below

-->

+1 -1

4 comments

1 changed file

david-mateogit

pr closed time in a month

pull request commentreactjs/reactjs.org

Update introducing-jsx.md

This is by design, since the very next example is about how that element doesn't need a closing tag. Thanks for the PR!

david-mateogit

comment created time in a month

PR opened reactjs/reactjs.org

WIP: add missing documentation URLs to /versions

Looks like we missed adding these since 16.9. Opening a WIP till we figure out where to get the documentation urls from.

+7 -0

0 comment

1 changed file

pr created time in a month

create barnchreactjs/reactjs.org

branch : threepointone-versions-docs-urls

created branch time in a month

issue commentreactjs/react-codemod

Any plans to make it work with TypeScript

It’s hard to comment without more details. If you could file a fresh issue with more details, what command you ran and what options you picked in the wizard. Ideally if you could make a small git repo that reproduces the problem, that would be great.

milichev

comment created time in a month

pull request commentreactjs/reactjs.org

Updated React and React Native links

Thanks very much for this!

visshaljagtap

comment created time in a month

push eventreactjs/reactjs.org

Vishal Jagtap

commit sha be17215d860b4a35e6b231b31001c1a9b527aa13

Updated React and React Native links (#2824) * DOC: Updated the React Native Home URL * Blog: Updated the React URL Link * Relative link added

view details

push time in a month

PR merged reactjs/reactjs.org

Reviewers
Updated React and React Native links CLA Signed

<!--

Thank you for the PR! Contributors like you keep React awesome!

Please see the Contribution Guide for guidelines:

https://github.com/reactjs/reactjs.org/blob/master/CONTRIBUTING.md

If your PR references an existing issue, please add the issue number below

-->

+10 -10

2 comments

10 changed files

visshaljagtap

pr closed time in a month

PR closed reactjs/reactjs.org

remove parantheses from onClick method

writing this.props.onClick() (with parantheses) invokes the passed method immediately. This causes an update of the component. In turn the render() method calls the method again, resulting in an infinite loop that finally crashes in a "Maximum depth exceeded" error.

<!--

Thank you for the PR! Contributors like you keep React awesome!

Please see the Contribution Guide for guidelines:

https://github.com/reactjs/reactjs.org/blob/master/CONTRIBUTING.md

If your PR references an existing issue, please add the issue number below

-->

+1 -1

5 comments

1 changed file

nodermatt

pr closed time in a month

pull request commentreactjs/reactjs.org

remove parantheses from onClick method

This feels like a nit at this point. I’m going to close this PR. Thanks for your input!

nodermatt

comment created time in a month

issue closedfacebook/react

Bug: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided

when using the window command and createObjectURL etsou having this error: TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.

the code looks something like this:

const blobUrl = window. URL.createObjectURL(print);
window.open(blobUrl);

being print the answer i sell an API, where I search my pdf. But when I use the createObjectURL it of this error.

How do I use this in ReactJS?

closed time in a month

Yuri-Tiofilo

issue commentfacebook/react

Bug: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided

This isn’t related to React at all, so I’m going to close this issue. I recommend using a community resource like stack overflow. Thanks!

Yuri-Tiofilo

comment created time in a month

Pull request review commentreactjs/reactjs.org

Updated React and React Native links

 title: "GraphQL Introduction" author: [schrockn] --- -At the React.js conference in late January 2015, we revealed our next major technology in the React family: [Relay](http://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html). +At the React.js conference in late January 2015, we revealed our next major technology in the React family: [Relay](https://reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html). 

This should be a relative link instead

visshaljagtap

comment created time in a month

pull request commentreactjs/reactjs.org

remove parantheses from onClick method

This isn’t right, ()=>... is a function and don’t get immediately called. Can you reproduce the problem in a codesandbox?

nodermatt

comment created time in a month

issue commentreactjs/reactjs.org

Using instance props with new lifecycle methods

Questions like these probably belong on stack overflow, they’re not directly related to enhancing the docs.

mrchief

comment created time in a month

issue closedreactjs/react-codemod

Cannot find module eslint

I'm trying to run sort comp with npx react-codemod sort-comp src but it fails saying that it cannot find eslint. I just ran npx react-codemod rename-unsafe-lifecycles src without any issues.

Any ideas how to resolve this?

Output below

ERR src/components/objects/ObjectMatcher.tsx Transformation error (Cannot find module 'eslint' Require stack: - /Users/hank/.npm/_npx/28372/lib/node_modules/react-codemod/transforms/sort-comp.js - /Users/hank/.npm/_npx/28372/lib/node_modules/react-codemod/node_modules/jscodeshift/src/Worker.js)
Error: Cannot find module 'eslint'
Require stack:
- /Users/hank/.npm/_npx/28372/lib/node_modules/react-codemod/transforms/sort-comp.js
All done. 
Results: 
349 errors
0 unmodified
0 skipped
0 ok
Time elapsed: 3.705seconds

closed time in a month

hankolsen

issue commentreactjs/react-codemod

Cannot find module eslint

released in v5.2.0. Closing this, but lemme know if it works fine!

hankolsen

comment created time in a month

pull request commentreactjs/react-codemod

Fixes #51: Declare eslint dependency

Done, released in v5.2.0. Give it a spin and lemme know how it goes?

laurens-dg

comment created time in a month

push eventreactjs/react-codemod

Wesley Yee

commit sha 1f04dd8245f7335dcd10bb07c188ccb8be62d29e

Fix pure component transform edge cases (#255) * Lexical declarations cannot be combined with the default keyword * Remove unused super class import * Don't include props argument if not used

view details

push time in a month

PR merged reactjs/react-codemod

Fix pure component transform edge cases

case 1: Default exported classes When converting a class combined with a default export, to a pure component, you end up creating a syntax error. This is because you cannot combine the default keyword with a lexical declaration. This PR separates the declaration from the export in this case.

case 2: Unused super class import remains When converting to a pure functional component the old super class may have a named import that is no longer used. This should be removed.

case 3: Props argument exists even if its never used

+75 -11

3 comments

6 changed files

wesleyyee

pr closed time in a month

pull request commentreactjs/react-codemod

Fix pure component transform edge cases

Thank you for your PR!

wesleyyee

comment created time in a month

issue closedfacebook/react

Bug:Erro no teste de repositorio

Erros nos componentes do React.js

closed time in a month

carlosgustavo

issue commentfacebook/react

Bug:Erro no teste de repositorio

Closing, happy to reopen if there’s more information.

carlosgustavo

comment created time in a month

Pull request review commentfacebook/react

Flare: Fix listener upgrade bug

 export function addResponderEventSystemEvent(     document,   );   if (passiveBrowserEventsSupported) {-    addEventCaptureListenerWithPassiveFlag(+    fbListener = addEventCaptureListenerWithPassiveFlag(       document,       topLevelType,       listener,       passive,     );   } else {-    addEventCaptureListener(document, topLevelType, listener);+    fbListener = addEventCaptureListener(document, topLevelType, listener);   }-  return listener;+  return fbListener || listener;

I'll be honest, this code is a bit confusing. I can trace it out and it looked ok, but I defer to your judgement here.

trueadm

comment created time in a month

Pull request review commentfacebook/react

Flare: Fix listener upgrade bug

 export function addResponderEventSystemEvent(     document,   );   if (passiveBrowserEventsSupported) {-    addEventCaptureListenerWithPassiveFlag(+    fbListener = addEventCaptureListenerWithPassiveFlag(       document,       topLevelType,       listener,       passive,     );   } else {-    addEventCaptureListener(document, topLevelType, listener);+    fbListener = addEventCaptureListener(document, topLevelType, listener);   }-  return listener;+  return fbListener || listener; } -export function removeActiveResponderEventSystemEvent(+export function removePassiveResponderEventSystemEvent(   document: Document,   topLevelType: string,   listener: any => void, ) {-  if (passiveBrowserEventsSupported) {-    document.removeEventListener(topLevelType, listener, {-      capture: true,-      passive: false,-    });+  if (listener.remove) {
  if (listener.remove != null) {
trueadm

comment created time in a month

push eventfacebook/react

Kerollos Magdy

commit sha 9e5626cdde7d1d698458729197707c992726c6e5

Fix yarn warning on running 'yarn build-for-devtools' (#18232) fixes #18231

view details

push time in a month

PR merged facebook/react

Fix yarn warning on running 'yarn build-for-devtools' CLA Signed

fixes #18231

Summary

Remove the "--" in yarn build-for-devtools script

+1 -1

6 comments

1 changed file

kerolloz

pr closed time in a month

issue closedfacebook/react

Warning: Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. --> warning From Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts.

Steps To Reproduce

  1. yarn build-for-devtools

The current behavior

image

The expected behavior

image

closed time in a month

kerolloz

pull request commentfacebook/react

Fix yarn warning on running 'yarn build-for-devtools'

Looks good to me. Thank you for your PR!

kerolloz

comment created time in a month

issue commentfacebook/react

Bug: hooks are not allowed with asyc

Please make a reproducible example with codesandbox, or a git repo that demonstrates this problem. Thank you!

jinhale

comment created time in a month

issue commentfacebook/react

Useeffect asynchronous processing reported a warning

it's likely that your component is unmounting (for whatever reason) before the async call completes. In which case, the warning is correct.

lgf196

comment created time in a month

issue closedfacebook/react

set blank_issues-enabled to false in config.yml

Anyways blank issues will be closed, so why allow them in the first place?

Thus, disable Blank Issue option in config.yml https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser

closed time in a month

nainardev

issue commentfacebook/react

set blank_issues-enabled to false in config.yml

People often submit issues that don't use the standard template, and I don't think we want to lock out every one at the moment. It's alright. Thanks!

nainardev

comment created time in a month

issue commentfacebook/react

Bug(regression): PropTypes.resetWarningCache has no effect in react@next

importing the cache would defeat the purpose of inlining, which is to have fewer dependencies. Tricky.

eps1lon

comment created time in a month

issue closedfacebook/react

[Dependencies] React uses both array-unique and array-uniq

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. -->

React version: 16.13.0

Steps To Reproduce

  1. See https://github.com/facebook/react/issues/18264#issuecomment-597066824

<!-- Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Issues without reproduction steps or code examples may be immediately closed as not actionable. -->

<!-- Please provide a CodeSandbox (https://codesandbox.io/s/new), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve. -->

The current behavior

These two packages does the same thing. array-uniq is better as it uses Set, while array-unique is last updated years ago. why two packages doing same thing

The expected behavior

Uses either one

closed time in a month

nainardev

issue commentfacebook/react

[Dependencies] React uses both array-unique and array-uniq

We can’t do much about what our dev dependencies pull in. This isn’t really an issue, but thanks for the concern!

nainardev

comment created time in a month

issue commentfacebook/react

Bug: renderToStaticMarkup throw warning about SVG PascalCase and camelCase naming

could you make a codesanbox version or a git repo that demonstrates this issue?

BiosBoy

comment created time in a month

pull request commentfacebook/react

ReactDOM.useEvent add flag and entry point

Yeah haha I figured. :shipit:

trueadm

comment created time in a month

IssuesEvent

issue closedfacebook/react

[Dependencies] React uses array-unique and array-uniq

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. -->

React version: 16.13.0

Steps To Reproduce

  1. Look into package.json

<!-- Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Issues without reproduction steps or code examples may be immediately closed as not actionable. -->

<!-- Please provide a CodeSandbox (https://codesandbox.io/s/new), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve. -->

The current behavior

These two packages does the same thing. array-uniq is better as it uses Set, while array-unique is last updated years ago. why two packages doing same thing

The expected behavior

Uses either one

closed time in a month

nainardev

issue commentfacebook/react

[Dependencies] React uses array-unique and array-uniq

I'm not sure what you mean, we don't use either of those? https://github.com/facebook/react/blob/master/package.json

nainardev

comment created time in a month

push eventreactjs/reactjs.org

Jonathan Chhabra

commit sha 617021f886e5ab7c5818e5e9ee63ae4c48ec0547

Make React.memo documentation more clear (#2762) * Make React.memo documentation more clear * Update reference-react.md Co-authored-by: Sunil Pai <threepointone@fb.com>

view details

push time in a month

PR merged reactjs/reactjs.org

Make React.memo documentation more clear CLA Signed

Just a small tweak to the language explaining React.memo.

I had a discussion on Reactiflux that left me thinking that the language could be tweaked a bit here to further emphasize that it only cares about Props + "affects" seems misleading since it doesn't do anything to your props.

+1 -1

3 comments

1 changed file

Sonicrida

pr closed time in a month

issue commentfacebook/react

Bug: using hooks inside a named forwardRef callback causes a lint error

Oh hmm yeah. Lemme think about this some more.

KevinSjoberg

comment created time in a month

more