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

Question: Request for Block hydration example #5998

Closed
rufioTR opened this issue Apr 5, 2018 · 3 comments
Closed

Question: Request for Block hydration example #5998

rufioTR opened this issue Apr 5, 2018 · 3 comments
Labels
[Feature] Block API API that allows to express the block paradigm. [Type] Help Request Help with setup, implementation, or "How do I?" questions.

Comments

@rufioTR
Copy link

rufioTR commented Apr 5, 2018

Maybe it's a kind of noobish question, but I'm looking for a solid way (as far as "solid" can be a word in the current gutenberg process ;)) to hydrate blocks on the client side.

example:

import * as React from 'react'
const { registerBlockType } = wp.blocks



registerBlockType('example-blocks/super-simple-hello-click-block', {
  title: 'Super Simple Example Block',
  icon: 'megaphone',
  category: 'widgets',
  edit: () => <p>Only shown in Editor</p>,
  save: FrontendComponent
})

class FrontendComponent extends React.Component {

  render() {
    return (
      <div>
        <button onClick={() => console.log('Hello from console!')}>Click</button>
      </div>
    )
  }

}

with this approach the click event won't fire (server side rendering)

can anybody help me out here to hydrate the block and "reactivate" the events?

Thanks a lot :)

@gziolo gziolo added [Feature] Block API API that allows to express the block paradigm. [Type] Help Request Help with setup, implementation, or "How do I?" questions. labels Apr 6, 2018
@brandonpayton
Copy link
Member

Hi @rufioTR,

This doesn't seem like a noobish question to me. :)

But the amount of friction one must overcome to hydrate a block as a React component makes me think it is not an expected use case, at least not yet.

Here are some reasons:

  1. @wordpress/element, available as the client-side global wp.element, doesn't currently export a hydrate method.
  2. It is technically possible using react-dom directly, but it's awkward. Blocks are saved as siblings, so if you want to satisfy the container argument of ReactDOM.hydrate( element, container ) your save function needs to render a container around the subtree that will be hydrated.
save: () => (
  <div class="my-block-container">
    <FrontendComponent />
  </div>
)

Then you'd need to query for elements with that class, and hydrate in those containers.

  1. To hydrate a React component, you need the props used to render the component. Your onClick example does not use block attributes, but most blocks do. To hydrate, you need all the information used to render the original, but that information is not explicitly provided with the rendered block. Information may be there, but you will have to retrieve it to render the element argument of hydrate( element, container ).

It would be nice if it was natural to add handlers such as onClick to the saved block and have them automatically applied on the front end, but today, blocks are treated like static content when rendered to the front end.

You may already know this, but you can specify a script to load with your block type on the front-end via register_block_type's 'script' argument. The script can wait for the DOMContentLoaded event, query for your blocks, and add dynamism to the static block content.

NOTE: I believe the above is correct but am far from a Gutenberg expert. @gziolo, is there anything you would correct or add here?

@gziolo
Copy link
Member

gziolo commented May 15, 2018

It would be nice if it was natural to add handlers such as onClick to the saved block and have them automatically applied on the front end, but today, blocks are treated like static content when rendered to the front end.

Yes, that's the thing. We don't support rehydrating on the front-end at all. We only render saved HTML with HTML comments stripped. To make it work you would have to use the same save function you used and use it on the frontend. Technically it is possible because React supports server-side rendering and is able to apply all event handlers after page is loaded without replacing already existing DOM elements.

@gziolo
Copy link
Member

gziolo commented May 15, 2018

By the way, I did some exploration how to render React components on the front-end in #5691, but I didn't get to make it work with blocks. I'm sure it is going to be explored in the future, but definitely not before Gutenberg gets merged into WordPress core.

I'm closing this issue, but feel free to ask more questions related to this topic.

@gziolo gziolo closed this as completed May 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. [Type] Help Request Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

3 participants