michielve
michielve

Reputation: 569

Re-render Gutenberg block without calling setAttributes?

Is it possible to make a Gutenberg component to re-render without having to call props.setAttributes()?

When my Gutenberg block is displayed, I'm doing an AJAX request to look if there is new data available and showing a "Loading..." text. If there is no data available, I just want to remove the "Loading..." text. But how do you do that without calling props.setAttributes() first?

Upvotes: 2

Views: 3340

Answers (2)

I took Mehmood Ahmad's answer as a pointer and decided to expand this state idea. So the problem with refreshing the block using props.setAttributes({something: Date.now()}); is that this attribute will persist perpeutally. You can check that it pollutes your real attributes if you switch to Code Editor view, it'll be in that HTML comment.

So, the object you use in your wp.blocks.registerBlockType's edit needs to be built upon or composed with wp.compose.withState. Since I also wanted to use another HOC, wp.data.withSelect, I chose the compose way.

window.wp.compose.compose(
    wp.data.withSelect( /* ... */ ),
    wp.compose.withState({something: ''})
)(function (props) {
 // Actually make use of props.something
});

Then wherever needed, for example in a click handler, you update it with:

props.setState({something: Date.now()});

It'll re-render the block without persisting the value. You must use props.something or nothing will happen.

Upvotes: 1

Mehmood Ahmad
Mehmood Ahmad

Reputation: 657

The blocks of Gutenberg are actually React Components and there are two major ways to trigger rendering in React one is to change props and the other one is to change state.

In Gutenberg props is equivalent to attributes but state is state. So you can add isLoading attribute on attributes with default value of true and when you receive ajax response then you can switch this to false.

As technically isLoading is not a part of your block attribute so my suggestion to you is to prefer state. Please note that you can only define state in Class Components of React or by using hooks in functional components (on react v16 and above).

Upvotes: 3

Related Questions