Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught Error: Must provide a ref to the DOM element to be observed. #4

Closed
csantiago132 opened this issue Feb 25, 2018 · 11 comments
Closed

Comments

@csantiago132
Copy link

Amazing plugin and thanks for open-sourcing this! maybe im doing something wrong but im folowing the instructions and getting an error

Uncaught Error: Must provide a ref to the DOM element to be observed.
    at Observed.observe (Observed.js:122)
    at Observed.componentDidMount (Observed.js:83)
    at commitLifeCycles (react-dom.development.js:8770)
    at commitAllLifeCycles (react-dom.development.js:9946)
    at HTMLUnknownElement.callCallback (react-dom.development.js:542)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:581)
    at invokeGuardedCallback (react-dom.development.js:438)
    at commitRoot (react-dom.development.js:10050)
    at performWorkOnRoot (react-dom.development.js:11017)
    at performWork (react-dom.development.js:10967)

this is the main container

import React from 'react';
import Observed from 'react-observed';
import 'intersection-observer';

// containers
import Introduction from './views/Introduction';
import FeaturedProjects from '../FeaturedProjects';
import MyInformation from '../MyInformation';

const Homepage = () => (
  <main>
    <Introduction />
    <Observed
      initialViewState
      onChange={isInView => {}}
      options={{
        root: null,
        rootMargin: '0px 0px -160px 0px',
        threshold: [0, 0.25, 0.5, 0.75, 1]
      }}
    >
      {({ isInView, mapRef }) => (

          <FeaturedProjects isInView={isInView} mapRef={mapRef} />
   
      )}
    </Observed>
  </main>
);

export default Homepage;

and this is the component wrapped in it, its a stateless pure function component

const FeaturedProjects = ({ isInView, mapRef }) => (
  <section ref={mapRef} className="featured-projects">
    {isInView ? (
        <ProjectPreview
          number="01"
          project={projectTest}
          link="/"
          mainImage={mainImage}
        />
    ) : (
      <span>not in view.</span>
    )}
  </section>
);
export default FeaturedProjects;

Also, do I need the ternary operator? can I leave it blank just to render it if in view? thanks again for the help in advance

@jscottsmith
Copy link
Owner

jscottsmith commented Feb 25, 2018

Thanks @csantiago132. So, that's weird. Unless I'm missing something it seems like you're doing everything right so I'm not sure why your seeing that error. Could you provide the repo for me to look at?

do I need the ternary operator?

Nope, you could do the following:

<section ref={mapRef} className="featured-projects">
    {isInView && (
        <ProjectPreview
          number="01"
          project={projectTest}
          link="/"
          mainImage={mainImage}
        />
    )}
</section>

@csantiago132
Copy link
Author

@jscottsmith sure and thanks! ill add you since I have it private at the moment, branch is under feature/appUpdates dont know if it helps but the app is SSR at this time and im in the middle of consolidating files

@jscottsmith
Copy link
Owner

Hmm, ya this seems likely to be SSR related. Was the following thrown on the client or server?

Uncaught Error: Must provide a ref to the DOM element to be observed.

I can't seem to get that Error you were seeing -- instead I'm getting the following error which seems to be caused by a prop validation I used in the the Observed component.

Dynamic page loading failed ReferenceError: Element is not defined

I'll do some SSR testing today and see if can get a patch started.

@csantiago132
Copy link
Author

csantiago132 commented Feb 25, 2018

@jscottsmith both

Uncaught Error: Must provide a ref to the DOM element to be observed.

^^ on the web console

Dynamic page loading failed ReferenceError: Element is not defined

^^on the terminal

I even tried to pass document.viewport in

options={{
        root: document.viewport,
        ...}}

but got nothing

thanks again for the time taken

@jscottsmith
Copy link
Owner

jscottsmith commented Feb 26, 2018

I even tried to pass document.viewport in

Ya, it's actually due to the mapRef not returning a reference to the element when <Observed> mounts which is necessary to set up the IntersectionObserver -- but I'm really not sure why this is a problem in your app.

Published a fix for the SSR issue but it seems unrelated as I'm still seeing the error in your project.

Edit:

Actually, I'm thinking it may be due to how your project is setup. Something unique is happening in your build where the <Observed> component's componetDidMount() lifecycle hook is called before the the ref callbacks have been made. Pausing execution in the cDM, the <FeaturedProjects> hasn't even mounted yet and is not in the DOM. I think this is due to some of the code splitting or other async helpers this build is using (guessing?) as that is not normal React behavior. I also wonder if it only happens in the dev environment as opposed to a production build.

Maybe you have an idea of why this is happening?

Note that you can work around this behavior by just observing a <div> that wraps your FeaturedProjects component -- or move Observed inside FeaturedProjects.

@csantiago132
Copy link
Author

@jscottsmith I think that maybe it’s the Loadable component I’m using to async load components/code split the app. I’ll try and use your SSR fix and Call the component without it. If this is the cause, I’ll let you know so you can be aware/add it to the README. I’ll get back to you tonight and let you know any updates. Thanks again!!

@csantiago132
Copy link
Author

ok so basically, the best use-case for <Observed> is to wrap it around components/images directly instead of using it on the Container? im fiddling with it at the moment and will try everything noted here

@csantiago132
Copy link
Author

csantiago132 commented Feb 26, 2018

closing since there is support for SSR now and theres a fix for it, also, its due to my environment/setup and its not related to this plugin. Thanks again for everything!

EDIT:

Its due for using Loadable (used for code-splitting/async helper) on the container where <Observed> is being called. once I load the container without Loadable, it works as expected

Note to future-self:

Do not async load the container with Loadable.js where the <Observed> component will be used to avoid this issue as noted above:

Something unique is happening in your build where the component's componetDidMount() lifecycle hook is called before the the ref callbacks have been made. Pausing execution in the cDM, the hasn't even mounted yet and is not in the DOM

@jscottsmith
Copy link
Owner

Good to know, thanks for the update on the Loadable behavior and for filing this issue in the first place. I'll see about adding a note/warning somewhere in the readme about using these async helpers so others don't get tripped up too.

@csantiago132
Copy link
Author

csantiago132 commented Feb 26, 2018

thank you for taking the time to see the code and help to solve this promptly!

also, @jscottsmith are contributions welcomed? I ran into a pickle running unit test on Enzyme, I can add it to the README if you like. here's what you have to do to make the unit test pass

const renderedComponent = shallow(<MyComponentToBeTested isInView />);

simply pass the isInView as a prop to the component. This is at least on an Enzyme/Jest environment doing Shallow Rendering, don't know how it works on other environments but pretty sure other people can add theirs too

@jscottsmith
Copy link
Owner

@csantiago132 Of course, contributions are more than welcome. I'm not totally sure if the enzyme test is relevant enough to be documented but if you have an idea just open a PR and we can discuss there. It could definitely be helpful to document some of these scenarios that may be more commonly encountered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants