Skip to content

Commit

Permalink
Update Interactivity API documentation to reference withSyncEvent().
Browse files Browse the repository at this point in the history
  • Loading branch information
felixarntz committed Jan 21, 2025
1 parent 21e51be commit a582f01
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
46 changes: 43 additions & 3 deletions docs/reference-guides/interactivity-api/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,8 @@ const { state } = store( 'myPlugin', {
} );
```

You may want to add multiple such `yield` points in your action if it is doing a lot of work.

As mentioned above with [`wp-on`](#wp-on), [`wp-on-window`](#wp-on-window), and [`wp-on-document`](#wp-on-document), an async action should be used whenever the `async` versions of the aforementioned directives cannot be used due to the action requiring synchronous access to the `event` object. Synchronous access is required whenever the action needs to call `event.preventDefault()`, `event.stopPropagation()`, or `event.stopImmediatePropagation()`. To ensure that the action code does not contribute to a long task, you may manually yield to the main thread after calling the synchronous event API. For example:

```js
Expand All @@ -885,16 +887,17 @@ function splitTask() {

store( 'myPlugin', {
actions: {
handleClick: function* ( event ) {
handleClick: withSyncEvent( function* ( event ) {
event.preventDefault();
yield splitTask();
doTheWork();
},
} ),
},
} );
```

You may want to add multiple such `yield` points in your action if it is doing a lot of work.
You may notice the use of the [`withSyncEvent()`](#withsyncevent) utility function in this example. This is necessary due to an ongoing effort to handle store actions asynchronously by default, unless they require synchronous event access. Otherwise a deprecation warning will be triggered, and in a future release the behavior will change accordingly.


#### Side Effects

Expand Down Expand Up @@ -1253,6 +1256,43 @@ store( 'mySliderPlugin', {
} );
```

### withSyncEvent()

Actions that require synchronous event access need to use the `withSyncEvent()` function to wrap their handler callback. This is necessary due to an ongoing effort to handle store actions asynchronously by default, unless they require synchronous event access. Therefore, as of Gutenberg `TODO: Add release number here!` / WordPress 6.8 all actions that require synchronous event access should use the `withSyncEvent()` utility wrapper function. Otherwise a deprecation warning will be triggered, and in a future release the behavior will change accordingly.

Only very specific event methods and properties require synchronous access, so it is advised to only use `withSyncEvent()` when necessary. The following event methods and properties require synchronous access:

* `event.currentTarget`
* `event.preventDefault()`
* `event.stopImmediatePropagation()`
* `event.stopPropagation()`

Here is an example, where one action requires synchronous event access while the other one does not:

```js
// store
import { store, withSyncEvent } from '@wordpress/interactivity';

store( 'myPlugin', {
actions: {
// `event.preventDefault()` requires synchronous event access.
preventNavigation: withSyncEvent( ( event ) => {
event.preventDefault();
} ),

// `event.target` does not require synchronous event access.
logTarget: ( event ) => {
console.log( 'event target => ', event.target );
},

// Not using `event` at all does not require synchronous event access.
logSomething: () => {
console.log( 'something' );
},
},
} );
```

## Server functions

The Interactivity API comes with handy functions that allow you to initialize and reference configuration options on the server. This is necessary to feed the initial data that the Server Directive Processing will use to modify the HTML markup before it's send to the browser. It is also a great way to leverage many of WordPress's APIs, like nonces, AJAX, and translations.
Expand Down
7 changes: 4 additions & 3 deletions packages/interactivity-router/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ The package is intended to be imported dynamically in the `view.js` files of int
```js
/* view.js */

import { store } from '@wordpress/interactivity';
import { store, withSyncEvent } from '@wordpress/interactivity';

// This is how you would typically use the navigate() action in your block.
store( 'my-namespace/myblock', {
actions: {
*goToPage( e ) {
// The withSyncEvent() utility needs to be used because preventDefault() requires synchronous event access.
goToPage: withSyncEvent( function* ( e ) {
e.preventDefault();

// We import the package dynamically to reduce the initial JS bundle size.
Expand All @@ -31,7 +32,7 @@ store( 'my-namespace/myblock', {
'@wordpress/interactivity-router'
);
yield actions.navigate( e.target.href );
},
} ),
},
} );
```
Expand Down

0 comments on commit a582f01

Please sign in to comment.