0

Code and corresponding console logs

Hi, so I've redacted some sensitive information from the screen shot, but you can see enough to see my problem.

Now, I'm trying to build the UI for a site that gets data from a weather station. I'm trying to use react-google-maps' InfoBox, which disables mouse events by default. It seems that to enable mouse events, you must wait until the DOM is loaded, and then add the event handlers.

react-google-maps' InfoBox fires an onDomReady event (perhaps even upon adding more divs) but seems to never fire an onContentChanged event (I've looked in the node_modules code).

The content I'm putting in the InfoBox is basically a div with a string ref for each type of weather data. Sometimes there comes along a new type of weather data so I want to put that in also, and have the ref be available / usable.

However, immediately after the new divs have been added (and the DOM has been updated to show them), when I try to console log the DOM nodes (the refs refer to the nodes because they are divs and not a custom built component) the latest added ones are undefined. They do become a div (not undefined) a few renders later.

I've contemplated that this may be because
1) the DOM is not being updated before I'm trying to access the refs,
but indeed the UI shows the new divs,
2) string refs are deprecated (React 16.5),
but they work for the divs in comonentDidMount and eventually for new divs in componentDidUpdate,
3) executing the code within the return value of render may be run asynchronously with componentDidMount,
but I also tried setTimeout with 3000 ms to the same effect,
4) of something to do with enumerable properties,
but getOwnProperties behaves the same way.

In the end I decided I'll console log this.refs and Object.keys(this.refs) within the same few lines of code (shown in the screen shot), and you can see that within one console log statement (where Object.keys was used in the previous line) that while this.refs is an object with 8 keys, the two most recently added refs don't appear in Object.keys(this.refs).

This is probably a super complex interaction between react-google-maps' InfoBox, React's refs, and JavaScript's Object.keys, but it seems like it should be simple and confuses me to a loss.
Can anyone shed some light on why this might be happening??

The code looks something alike:

class SensorInfoWindow extends React.Component {
 handleIconClick = () => {
   // do stuff here
 }

 componentDidMount() {
   this.addClickHandlers();
 }

 componentDidUpdate() {
   this.addClickHandlers();
 }

 addClickHandlers = () => {
   const keys = Object.keys(this.refs);

   for(let i=0; i<keys.length; i++) {
     const key = keys[i];

     let element = this.refs[key];
     if (element !== undefined)
       element.addEventListener('click', this.handleIconClick);
   }
 }

 render() {
   const { thissensor, allsensors } = this.props;
   let divsToAddHandlersTo = [];

   const sensorkeys = Object.keys(allsensors);

   for (let i=0; i<sensorkeys.length; i++) {
     divsToAddHandlersTo.push(
       <div
         ref={'stringref' + i}
       />
         {/* children here, using InfoBox */}
       </div>
     );
   }

   return (
     <div>
       {divsToAddHandlersTo}
     </div>
   );
 }
}

This is, in essence, the component.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
plainOldNerd
  • 305
  • 2
  • 8
  • Can you please show your `render` function? If refs are added at a later time, it should be reflected in the `refs`-object, but not in the object returned by `Object.keys` because it captures the keys in the object as that specific time – Phillip Jul 18 '19 at 12:59
  • @Phillip, I've added the essential lifecycle code of the component. But I'm thinking even if there's a small time lapse between defining the 'keys' variable and console logging it with the object it is taking keys of, it would only be nanoseconds (the console log is on the next line), right?! It seems unlikely that the refs will update in those few nanoseconds every time! Thanks for taking the time to help, by the way. I appreciate it. – plainOldNerd Jul 18 '19 at 23:54

0 Answers0