7

To give a bit of context, I am conducting a research focused on digital marketing and user experience. To enable the research, it is essential that I am able to get event logs from every component in an UI so I am, then, able to create datasets of usability pattern.

To do so in a web interface, e.g. using JavaScript, that's very simple.

window.addEventListener("someEvent", (e) => {//do something with the data});

The e element gives me everything I need, and If I want to listen to all window events, I can run a for loop through the window object events and add an event listener to each. My issue is with mobile development. For cross application reasons, am I am using React Native to try to create the same effect as window.addEventListener to mobile apps.

This is my first time using React Native. After a bit of searching, I am now aware that React Native does not have a window object (at least not as we understand window in JavaScript) and that the interface is translated to the platform native components, so document.getElementBy... would't work either.

What I though of was refs. I would only need to add a reference to the top component App. So what I have working so far:

export default function App() {
  const viewRef = useRef();

  useEffect(() => {
    //I can use ref here to iterate through all events of View and
    //bind event listeners to it
  }, [viewRef]);

  return (
    <View
      ref={viewRef}
      style={styles.container}
      onTouchEnd={(e) => {
        console.log(e.target);
      }}
    >
      <DummyComponent />
    </View>
  );
}

onTouchEnd event is bind to the top-layer component, so I can get everything that is a child of it. In that useEffect, I can do the same thing I would with JavaScript's window.

So I guess this is one way to do it. However, in my research I would like to enable any React Native app to begin logging events seamlessly. The state of the art would be creating a dependency that would being logging everything simply by installing it. That said, how can I iterate a React Native application to find Views and bind their events, without need to add ANYTHING to the actual component?

In JavaScript it would be something like:

document.getElementsByTagName("View").map((view) => {//bind view events});
Pelicer
  • 1,348
  • 4
  • 23
  • 54
  • 1
    `To enable the research, it is essential that I am able to get event logs from every component in an UI`. There are tools for this that will do a better job than you could come up with by rolling your own. https://segment.com/docs/connections/sources/catalog/libraries/mobile/react-native/ or https://www.npmjs.com/package/@heap/react-native-heap – Adam Jenkins Aug 29 '22 at 13:19
  • 1
    Thanks for the tips. However, I would still like to know how I can accomplish this. – Pelicer Aug 29 '22 at 18:17
  • This probably isn't like the best answer, but one way would be to change the `defaultProps` of the component before rendering. I did a similar thing to set the default `fontSize` and `fontFamily` for every `Text` component, you could do the same for `onTouchEnd` for every `View` component for example – Luís Mestre Sep 07 '22 at 01:28
  • Without completely understanding your endgoal (rejecting 3rd party tools), your "javascript" solution would also fail with react, as the dom could easily change and your events would become orphants. – Esben Damgaard Sep 07 '22 at 11:11
  • @LuísMestre that seems promising. How so? Can you give me a simple dummy snippet? – Pelicer Sep 07 '22 at 15:11

1 Answers1

0

So I'm not sure if this can help, but you can change the defaultProps of a component on start of your application.

So using your code as example you could do something like this:

const listener = e => {
  console.log(e);
}

View.defaultProps = {
  ...View.defaultProps, // maintains original default props
  onTouchEnd: listener
};

Basically this way you can have a global listener for each View component

Luís Mestre
  • 1,851
  • 1
  • 11
  • 29
  • Thanks, Luís! Do you have any insights in how I could get all the View elements of the current component? Kind of a document.getElementByTagName("View")? – Pelicer Sep 28 '22 at 12:49
  • Borrowing this answer from another stackoverflow question: `window` and `document` are part of the web standard, not JavaScript (ECMA standard) itself. `document` is part of the DOM standard. React Native, although indeed runs on JavaScript for controlling the render, does not have a standards-compliant DOM implementation. So many (if not most) web-based (or DOM-based) React examples are not applicable to React Native, especially those doing DOM-manipulation. – Luís Mestre Sep 29 '22 at 22:36