alex-cory/react-useportal

Can't show modal on page load without opening event

Opened this issue · 16 comments

Whenever I want to show modal on render(make it visible without opening event) I get
Warning: Expected server HTML to contain a matching <div> in <div>.

My Code;

const SignInModal = () => {
  var { openPortal, closePortal, isOpen, Portal } = usePortal({
    closeOnEsc: true,
    // bindTo: typeof window !== 'undefined' && document.getElementById('__next'),
  })

  const modalElem = !isOpen && (
    <Portal>
      <ModalBox closeModal={closePortal}>
        <div className="modal__mid1">
          <h4 className="header--medium">Sign In to Walkway</h4>
          <InputText_1>Email or Username</InputText_1>
          <InputText_1>Password</InputText_1>
          <div className="modal__">
            <span>Forgot Password</span>
          </div>
          <div className="modal__mainBtn">
            <div className="modal__mainBtn__line" />
            <TextButton size="18">Sign Up</TextButton>
            <div className="modal__mainBtn__line" />
          </div>
          <span>or</span>
          <div className="modal__">
            <button className="haloOnHov socialMediaBtn">
              <div
                className="socialMediaBtn__icon"
                style={{
                  backgroundImage: `url('../static/icons/fb.svg')`,
                }}
              />
              Sign In with Facebook
            </button>
          </div>
          <p>
            Don’t have an account? <span>Register Now</span>
          </p>
        </div>
      </ModalBox>
    </Portal>
  )

  // return modalElem
  return {
    SignIn_modal: () => modalElem,
    openPortal,
    isOpen,
  }
}

could you please make a codesandbox :)

sounds like your app is SSR?

sounds like your app is SSR?

Yes, it's on next.js
I'm trying to recreate it on codesandbox rn

BUT, from 1st glance, sounds like in your case, you could just set the default of isOpen to be true.
i.e.

const { Portal, isOpen } = usePortal({
  isOpen: true
})

BUT, from 1st glance, sounds like in your case, you could just set the default of isOpen to be true.
i.e.

const { Portal, isOpen } = usePortal({
  isOpen: true
})

BUT, from 1st glance, sounds like in your case, you could just set the default of isOpen to be true.
i.e.

const { Portal, isOpen } = usePortal({
  isOpen: true
})

Nope, still same problem,
It renders it in a very weird way and screws up whole DOM

btw, try restarting server on codesandbox if you don't see modal's html on first load

Let me clarify what you're trying to do. You want onMount for the modal to be open?

also

Are you making sure to pass the event to openSignInModal? i.e.

<button onClick={e => openSignInModal(e)}>Open Signin Modal</button>

Yes, and yes I want it to be opened by default

BUT, from 1st glance, sounds like in your case, you could just set the default of isOpen to be true.
i.e.

const { Portal, isOpen } = usePortal({
  isOpen: true
})

Nope, still same problem,
It renders it in a very weird way and screws up whole DOM

That's weird, because when I do that, it pops up. Could you post a screenshot of what it looks like messed up?
image

How it loos like when isOpen: true
crashed
How should look like;
normal

Did you find any fix?

Not yet. Will take a look asap

have this same issue with both my portals and it's driving me a little nuts.

for clarification - it's not related to your package here @alex-cory, I had a homegrown Portal component and came here hoping that your package would resolve the issue, but alas it has not. Gonna continue to poke around and will share if I find a solution

found a hack/work-around for nextjs users...utilizing...dynamic importing no it's not perfect but considering a lot of times portals are called asynchronously I think this is a halfway decent solution.

const PureSlider = dynamic(
  () => import('./pureSlider').then(mod => mod.PureSlider),
  {
    ssr: false,
  }
);

If anyone has a better solution or suggestion I'm all ears 🛩️