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

Update the documentation of the block editor and replace @wordpress/element with react #54908

Merged
merged 7 commits into from Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/contributors/code/coding-guidelines.md
Expand Up @@ -529,7 +529,7 @@ alert( `My name is ${ name }.` );
- Example: `document.body.classList.toggle( 'has-focus', nodeRef.current?.contains( document.activeElement ) );` may wrongly _add_ the class, since [the second argument is optional](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle). If `undefined` is passed, it would not unset the class as it would when `false` is passed.
- Example: `<input value={ state.selected?.value.trim() } />` may inadvertently cause warnings in React by toggling between [controlled and uncontrolled inputs](https://reactjs.org/docs/uncontrolled-components.html). This is an easy trap to fall into when eagerly assuming that a result of `trim()` will always return a string value, overlooking the fact the optional chaining may have caused evaluation to abort earlier with a value of `undefined`.

### `@wordpress/element` (React) Components
### React Components

It is preferred to implement all components as [function components](https://reactjs.org/docs/components-and-props.html), using [hooks](https://reactjs.org/docs/hooks-reference.html) to manage component state and lifecycle. With the exception of [error boundaries](https://reactjs.org/docs/error-boundaries.html), you should never encounter a situation where you must use a class component. Note that the [WordPress guidance on Code Refactoring](https://make.wordpress.org/core/handbook/contribute/code-refactoring/) applies here: There needn't be a concentrated effort to update class components in bulk. Instead, consider it as a good refactoring opportunity in combination with some other change.

Expand Down Expand Up @@ -756,7 +756,7 @@ When documenting an example, use the markdown <code>\`\`\`</code> code block to
*/
````

### Documenting `@wordpress/element` (React) Components
### Documenting React Components

When possible, all components should be implemented as [function components](https://reactjs.org/docs/components-and-props.html#function-and-class-components), using [hooks](https://reactjs.org/docs/hooks-intro.html) for managing component lifecycle and state.

Expand Down
2 changes: 1 addition & 1 deletion docs/explanations/architecture/modularity.md
Expand Up @@ -43,7 +43,7 @@ function MyApp() {
```php
// myplugin.php
// Example of script registration dependending on the "components" and "element packages.
wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "wp-element" ) );
wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "react" ) );
```

```js
Expand Down
Expand Up @@ -58,8 +58,8 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is uppercase also how the default React scripts adds the window variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

var el = React.createElement;

blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
edit: function ( props ) {
Expand Down Expand Up @@ -93,7 +93,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
);
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand Down Expand Up @@ -134,8 +134,8 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
var el = React.createElement;

blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
edit: function ( props ) {
Expand All @@ -155,7 +155,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
);
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand All @@ -180,8 +180,8 @@ Edit the asset file to include the block-editor dependency for the scripts.
<?php return
array( 'dependencies' =>
array(
'react',
'wp-blocks',
'wp-element',
'wp-block-editor',
'wp-polyfill'
),
Expand Down
Expand Up @@ -95,8 +95,8 @@ registerBlockType( 'gutenberg-examples/example-04-controls-esnext', {
{% Plain %}

```js
( function ( blocks, blockEditor, element ) {
var el = element.createElement;
( function ( blocks, blockEditor, React ) {
var el = React.createElement;
var RichText = blockEditor.RichText;
var AlignmentToolbar = blockEditor.AlignmentToolbar;
var BlockControls = blockEditor.BlockControls;
Expand Down Expand Up @@ -176,7 +176,7 @@ registerBlockType( 'gutenberg-examples/example-04-controls-esnext', {
);
},
} );
} )( window.wp.blocks, window.wp.blockEditor, window.wp.element );
} )( window.wp.blocks, window.wp.blockEditor, window.React );
```

{% end %}
Expand Down
Expand Up @@ -67,8 +67,8 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', {
{% Plain %}

```js
( function ( blocks, blockEditor, element ) {
var el = element.createElement;
( function ( blocks, blockEditor, React ) {
var el = React.createElement;
var RichText = blockEditor.RichText;
var useBlockProps = blockEditor.useBlockProps;

Expand Down Expand Up @@ -118,7 +118,7 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', {
);
},
} );
} )( window.wp.blocks, window.wp.blockEditor, window.wp.element );
} )( window.wp.blocks, window.wp.blockEditor, window.React );
```

{% end %}
Expand Down
12 changes: 6 additions & 6 deletions docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md
Expand Up @@ -55,8 +55,8 @@ registerBlockType( 'gutenberg-examples/example-dynamic', {
{% Plain %}

```js
( function ( blocks, element, data, blockEditor ) {
var el = element.createElement,
( function ( blocks, React, data, blockEditor ) {
var el = React.createElement,
registerBlockType = blocks.registerBlockType,
useSelect = data.useSelect,
useBlockProps = blockEditor.useBlockProps;
Expand Down Expand Up @@ -86,7 +86,7 @@ registerBlockType( 'gutenberg-examples/example-dynamic', {
} );
} )(
window.wp.blocks,
window.wp.element,
window.React,
window.wp.data,
window.wp.blockEditor
);
Expand Down Expand Up @@ -187,8 +187,8 @@ registerBlockType( 'gutenberg-examples/example-dynamic', {
{% Plain %}

```js
( function ( blocks, element, serverSideRender, blockEditor ) {
var el = element.createElement,
( function ( blocks, React, serverSideRender, blockEditor ) {
var el = React.createElement,
registerBlockType = blocks.registerBlockType,
ServerSideRender = serverSideRender,
useBlockProps = blockEditor.useBlockProps;
Expand All @@ -213,7 +213,7 @@ registerBlockType( 'gutenberg-examples/example-dynamic', {
} );
} )(
window.wp.blocks,
window.wp.element,
window.React,
window.wp.serverSideRender,
window.wp.blockEditor
);
Expand Down
Expand Up @@ -111,8 +111,8 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', {
{% Plain %}

```js
( function ( blocks, blockEditor, element ) {
var el = element.createElement;
( function ( blocks, blockEditor, React ) {
var el = React.createElement;
var RichText = blockEditor.RichText;
var useBlockProps = blockEditor.useBlockProps;

Expand Down Expand Up @@ -162,7 +162,7 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', {
);
},
} );
} )( window.wp.blocks, window.wp.blockEditor, window.wp.element );
} )( window.wp.blocks, window.wp.blockEditor, window.React );
```

{% end %}
24 changes: 12 additions & 12 deletions docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md
Expand Up @@ -41,8 +41,8 @@ registerBlockType( 'gutenberg-examples/example-06', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
var el = React.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;

Expand All @@ -62,7 +62,7 @@ registerBlockType( 'gutenberg-examples/example-06', {
return el( 'div', blockProps, el( InnerBlocks.Content ) );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand Down Expand Up @@ -241,8 +241,8 @@ registerBlockType( 'gutenberg-examples/example-06', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
var el = React.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
Expand All @@ -265,7 +265,7 @@ registerBlockType( 'gutenberg-examples/example-06', {
return el( 'div', blockProps, el( 'div', innerBlocksProps ) );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand Down Expand Up @@ -305,8 +305,8 @@ registerBlockType( 'gutenberg-examples/example-06', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
var el = React.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
Expand All @@ -328,7 +328,7 @@ registerBlockType( 'gutenberg-examples/example-06', {
return el( 'div', innerBlocksProps );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand Down Expand Up @@ -372,8 +372,8 @@ registerBlockType( 'gutenberg-examples/example-06', {
{% Plain %}

```js
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
( function ( blocks, React, blockEditor ) {
var el = React.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
Expand All @@ -398,7 +398,7 @@ registerBlockType( 'gutenberg-examples/example-06', {
},
// ...
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
} )( window.wp.blocks, window.React, window.wp.blockEditor );
```

{% end %}
Expand Down
Expand Up @@ -145,8 +145,8 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', {
Add the following to `block.js`

```js
( function ( blocks, element ) {
var el = element.createElement;
( function ( blocks, React ) {
var el = React.createElement;

blocks.registerBlockType( 'gutenberg-examples/example-01-basic', {
edit: function () {
Expand All @@ -156,7 +156,7 @@ Add the following to `block.js`
return el( 'p', {}, 'Hola mundo (from the frontend).' );
},
} );
} )( window.wp.blocks, window.wp.element );
} )( window.wp.blocks, window.React );
```

{% end %}
Expand All @@ -182,8 +182,8 @@ Create the asset file to load the dependencies for the scripts. The name of this
<?php return
array( 'dependencies' =>
array(
'react',
'wp-blocks',
'wp-element',
'wp-polyfill'
),
'version' => '0.1'
Expand Down
6 changes: 3 additions & 3 deletions docs/how-to-guides/data-basics/1-data-basics-setup.md
Expand Up @@ -18,18 +18,18 @@ Go ahead and create these files using the following snippets:
**src/index.js:**

```js
import { render } from '@wordpress/element';
import { createRoot } from 'react-dom';

function MyFirstApp() {
return <span>Hello from JavaScript!</span>;
}

const root = createRoot( document.getElementById( 'my-first-gutenberg-app' ) );
window.addEventListener(
'load',
function () {
render(
root.render(
<MyFirstApp />,
document.querySelector( '#my-first-gutenberg-app' )
);
},
false
Expand Down
16 changes: 10 additions & 6 deletions docs/how-to-guides/data-basics/2-building-a-list-of-pages.md
Expand Up @@ -150,8 +150,8 @@ The list of pages is short for now; however, the longer it grows, the harder it
Let’s start by adding a search field:

```js
import { useState } from 'react';
import { SearchControl } from '@wordpress/components';
import { useState, render } from '@wordpress/element';

function MyFirstApp() {
const [searchTerm, setSearchTerm] = useState( '' );
Expand Down Expand Up @@ -211,8 +211,9 @@ The `searchTerm` is now used as a `search` query parameter when provided. Note t
Finally, here’s how `MyFirstApp` looks once we wire it all together:

```js
import { useState } from 'react';
import { createRoot } from 'react-dom';
import { SearchControl } from '@wordpress/components';
import { useState, render } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';

Expand Down Expand Up @@ -359,8 +360,9 @@ And voilà! That's it.
All the pieces are in place, great! Here’s the complete JavaScript code of our app:

```js
import { useState } from 'react';
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
import { createRoot } from 'react-dom';
import { SearchControl, Spinner } from '@wordpress/components';
import { useState, render } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
Expand Down Expand Up @@ -421,12 +423,14 @@ function PagesList( { hasResolved, pages } ) {
);
}

const root = createRoot(
document.querySelector( '#my-first-gutenberg-app' )
);
window.addEventListener(
'load',
function () {
render(
<MyFirstApp />,
document.querySelector( '#my-first-gutenberg-app' )
root.render(
<MyFirstApp />
);
},
false
Expand Down
6 changes: 3 additions & 3 deletions docs/how-to-guides/data-basics/5-adding-a-delete-button.md
Expand Up @@ -142,7 +142,7 @@ wp.data.select( 'core' ).getLastEntityDeleteError( 'postType', 'page', 9 )
Here's how we can apply it in `DeletePageButton`:

```js
import { useEffect } from '@wordpress/element';
import { useEffect } from 'react';
const DeletePageButton = ({ pageId }) => {
// ...
const { error, /* ... */ } = useSelect(
Expand Down Expand Up @@ -252,8 +252,8 @@ Now we're ready to tell the user about any errors that may have occurred.
With the SnackbarNotices component in place, we're ready to dispatch some notifications! Here's how:

```js
import { useEffect } from 'react';
import { store as noticesStore } from '@wordpress/notices';
import { useEffect } from '@wordpress/element';
function DeletePageButton( { pageId } ) {
const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore );
// useSelect returns a list of selectors if you pass the store handle
Expand Down Expand Up @@ -307,8 +307,8 @@ And that's it!
All the pieces are in place, great! Here’s all the changes we've made in this chapter:

```js
import { useState, useEffect } from 'react';
import { useSelect, useDispatch } from '@wordpress/data';
import { useState, useEffect } from '@wordpress/element';
import { Button, Modal, TextControl } from '@wordpress/components';

function MyFirstApp() {
Expand Down