{"id":234228,"date":"2023-02-17T10:49:00","date_gmt":"2023-02-17T07:49:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=234228"},"modified":"2022-11-12T01:12:09","modified_gmt":"2022-11-11T22:12:09","slug":"creer-un-bloc-gutenberg-personnalise-partie-7-creez-vos-propres-composants-personnalises","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/creer-un-bloc-gutenberg-personnalise-partie-7-creez-vos-propres-composants-personnalises\/","title":{"rendered":"Cr\u00e9er un bloc Gutenberg personnalis\u00e9 &#8211; Partie 7\u00a0: Cr\u00e9ez vos propres composants personnalis\u00e9s"},"content":{"rendered":"\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, dans cette s\u00e9rie de didacticiels, nous avons \u00e9crit tout le code dans <code>registerBlockType()<\/code>la <code>edit<\/code>fonction de. Il est tout \u00e0 fait possible, et souvent recommand\u00e9, d&rsquo;affecter \u00e0 la place la modification \u00e0 un composant distinct. Ce faisant, nous pouvons utiliser des fonctionnalit\u00e9s telles que l&rsquo;\u00e9tat des composants et les m\u00e9thodes de cycle de vie. C&rsquo;est aussi beaucoup plus propre, lisible et fournit un code r\u00e9utilisable !<\/p>\n<p>Si vous n&rsquo;\u00eates pas familiaris\u00e9 avec la cr\u00e9ation de composants React ou les m\u00e9thodes d&rsquo;\u00e9tat et de cycle de vie, je vous recommande de lire d&rsquo;abord <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">le guide officiel de React sur ce sujet<\/a>.<\/p>\n<h2>D\u00e9finition d&rsquo;un composant de classe pour<code>edit<\/code><\/h2>\n<p>Vous pouvez d\u00e9finir un composant soit comme une fonction soit comme une classe. Avec un composant de classe, vous pouvez utiliser des fonctionnalit\u00e9s telles que les m\u00e9thodes d&rsquo;\u00e9tat et de cycle de vie. Cependant, dans les nouvelles versions de React (16+), vous pouvez utiliser les crochets React pour simuler les m\u00e9thodes d&rsquo;\u00e9tat et de cycle de vie \u00e0 l&rsquo;int\u00e9rieur des composants de fonction. Mais dans ce didacticiel, nous nous concentrerons sur la cr\u00e9ation d&rsquo;un composant de classe. Ce que nous avons cr\u00e9\u00e9 jusqu&rsquo;\u00e0 pr\u00e9sent dans cette s\u00e9rie, &quot;en ligne&quot; dans <code>registerBlockType()<\/code>for <code>edit<\/code>et <code>save<\/code>, sont des composants de fonction.<\/p>\n<p>Pour d\u00e9finir un composant de classe, nous \u00e9tendons WordPress&rsquo; <code>Component<\/code>(dans <code>wp.element<\/code>package), exactement comme vous \u00e9tendriez un composant de classe \u00e0 <code>React.Component<\/code>.<\/p>\n<p>Gardez \u00e0 l&rsquo;esprit que votre composant de classe doit inclure la fonction <code>render()<\/code>. Et \u00e0 cause du fonctionnement de Javascript, votre classe doit \u00eatre d\u00e9finie avant votre <code>registerBlockType()<\/code>appel (\u00e9crivez d&rsquo;abord votre composant de classe dans le fichier, et conservez-le <code>registerBlockType()<\/code>apr\u00e8s. Plus tard dans cet article, nous apprendrons comment s\u00e9parer les composants dans des fichiers s\u00e9par\u00e9s, exporter et inclure leur).<\/p>\n<p>Bref, comme \u00e7a :<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { Component } = wp.element;\n\u00a0\nclass FirstBlockEdit extends Component {\n    render() {\n        const { attributes, setAttributes } = this.props;\n        return ...\n    }\n}\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    edit: FirstBlockEdit,\n    save: (props) =&gt; { \n        return ...\n    }\n});<\/code><\/pre>\n<p>Les accessoires de <code>edit<\/code>sont automatiquement appliqu\u00e9s \u00e0 notre composant. N&rsquo;oubliez pas qu&rsquo;un composant de classe dont vous avez besoin pour faire r\u00e9f\u00e9rence aux accessoires avec <code>this.props<\/code>. Il est courant dans le noyau de WordPress Gutenberg d&rsquo;utiliser des composants s\u00e9par\u00e9s pour les <code>edit<\/code>fonctions car ils contiennent le plus souvent beaucoup plus de code. La <code>save<\/code>fonction peut souvent \u00eatre laiss\u00e9e \u00e0 <code>registerBlockType()<\/code>moins qu&rsquo;elle ne contienne \u00e9galement beaucoup de code.<\/p>\n<p>En faisant cela, vous pouvez maintenant \u00e9crire votre composant comme vous le feriez avec React. Vous pouvez ajouter des fonctions, des constructeurs, des \u00e9tats et des m\u00e9thodes de cycle de vie.<\/p>\n<p>Voici le code auquel nous nous sommes retrouv\u00e9s \u00e0 la derni\u00e8re \u00e9tape, converti en un composant de classe\u00a0:<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { Component } = wp.element;\nconst { RichText, InspectorControls, BlockControls, AlignmentToolbar } = wp.blockEditor;\nconst { ToggleControl, PanelBody, PanelRow, CheckboxControl, SelectControl, ColorPicker, Toolbar, IconButton } = wp.components;\n\u00a0\nclass FirstBlockEdit extends Component {\n\u00a0\n    render() {\n        const { attributes, setAttributes } = this.props;\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return (&lt;div className={alignmentClass}&gt;\n                &lt;InspectorControls&gt;\n                    &lt;PanelBody\n                        title=\"Most awesome settings ever\"\n                        initialOpen={true}\n                    &gt;\n                        &lt;PanelRow&gt;\n                            &lt;ToggleControl\n                                label=\"Toggle me\"\n                                checked={attributes.toggle}\n                                onChange={(newval) =&gt; setAttributes({ toggle: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;SelectControl\n                                label=\"What's your favorite animal?\"\n                                value={attributes.favoriteAnimal}\n                                options={[\n                                    {label: \"Dogs\", value: 'dogs'},\n                                    {label: \"Cats\", value: 'cats'},\n                                    {label: \"Something else\", value: 'weird_one'},\n                                ]}\n                                onChange={(newval) =&gt; setAttributes({ favoriteAnimal: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;ColorPicker\n                                color={attributes.favoriteColor}\n                                onChangeComplete={(newval) =&gt; setAttributes({ favoriteColor: newval.hex })}\n                                disableAlpha\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;CheckboxControl\n                                label=\"Activate lasers?\"\n                                checked={attributes.activateLasers}\n                                onChange={(newval) =&gt; setAttributes({ activateLasers: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                    &lt;\/PanelBody&gt;\n                &lt;\/InspectorControls&gt;\n                &lt;BlockControls&gt;\n                    &lt;AlignmentToolbar\n                        value={attributes.textAlignment}\n                        onChange={(newalign) =&gt; setAttributes({ textAlignment: newalign })}\n                    \/&gt;\n                    &lt;Toolbar&gt;\n                        &lt;IconButton\n                            label=\"My very own custom button\"\n                            icon=\"edit\"\n                            className=\"my-custom-button\"\n                            onClick={() =&gt; console.log('pressed button')}\n                        \/&gt;\n                    &lt;\/Toolbar&gt;\n                &lt;\/BlockControls&gt;\n                &lt;RichText \n                    tagName=\"h2\"\n                    placeholder=\"Write your heading here\"\n                    value={attributes.myRichHeading}\n                    onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                \/&gt;\n                &lt;RichText\n                    tagName=\"p\"\n                    placeholder=\"Write your paragraph here\"\n                    value={attributes.myRichText}\n                    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                \/&gt;\n            &lt;\/div&gt;\n        );\n    }\n}\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    category: 'common',\n    icon: 'smiley',\n    description: 'Learning in progress',\n    keywords: ['example', 'test'],\n    attributes: {\n        myRichHeading: {\n            type: 'string',\n        },\n        myRichText: {\n            type: 'string',\n            source: 'html',\n            selector: 'p'\n        },\n        textAlignment: {\n            type: 'string',\n        },\n        toggle: {\n            type: 'boolean',\n            default: true\n        },\n        favoriteAnimal: {\n            type: 'string',\n            default: 'dogs'\n        },\n        favoriteColor: {\n            type: 'string',\n            default: '#DDDDDD'\n        },\n        activateLasers: {\n            type: 'boolean',\n            default: false\n        },\n    },\n    supports: {\n        align: ['wide', 'full']\n    },\n    edit: FirstBlockEdit,\n    save: (props) =&gt; { \n        const { attributes } = props;\n\u00a0\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return (&lt;div className={alignmentClass}&gt;\n                &lt;RichText.Content \n                    tagName=\"h2\"\n                    value={attributes.myRichHeading}\n                \/&gt;\n                &lt;RichText.Content \n                    tagName=\"p\"\n                    value={attributes.myRichText}\n                \/&gt;\n                {attributes.activateLasers &amp;&amp; \n                    &lt;div className=\"lasers\"&gt;Lasers activated&lt;\/div&gt;\n                }\n            &lt;\/div&gt;\n        );\n    }\n});<\/code><\/pre>\n<p>Si vous avez d\u00e9structur\u00e9 <code>attributes<\/code>et <code>setAttributes<\/code>\u00e0 partir d&rsquo;accessoires comme nous l&rsquo;avons fait, tout ce que vous devez changer lorsque vous passez \u00e0 un composant de classe s\u00e9par\u00e9 est de changer une ligne ; <code>#9<\/code>de <code>props<\/code>\u00e0 <code>this.props<\/code>. Tout le code fonctionnera comme avant sans rien r\u00e9parer d&rsquo;autre. C&rsquo;est la beaut\u00e9 de la d\u00e9structuration. Si vous ne l&rsquo;avez pas d\u00e9structur\u00e9 et que vous vous y \u00eates r\u00e9f\u00e9r\u00e9 <code>props.attributes<\/code>directement, par exemple, vous devrez ajouter <code>this.<\/code>devant toutes les r\u00e9f\u00e9rences individuelles \u00e0 <code>attributes<\/code>et <code>setAttributes<\/code>partout.<\/p>\n<p>Commen\u00e7ons \u00e0 faire des choses que nous pouvons maintenant faire avec un composant de classe\u00a0!<\/p>\n<h2>D\u00e9finir les fonctions et<code>this<\/code><\/h2>\n<p>Certes, oui, vous pouvez d\u00e9finir des fonctions \u00e0 partir du <code>edit<\/code>composant de fonction, avant d&rsquo;appeler <code>return<\/code>. Mais personnellement, j&rsquo;ai toujours pr\u00e9f\u00e9r\u00e9 s\u00e9parer les fonctionnalit\u00e9s par la logique. Je trouve pr\u00e9f\u00e9rable de s\u00e9parer les fonctions \u00e0 des fins logiques et autres en dehors de la fonction responsable du rendu de la sortie. Certaines personnes pr\u00e9f\u00e8rent \u00e9galement appeler des fonctions dans des \u00e9v\u00e9nements, au lieu de les faire en ligne comme nous l&rsquo;avons fait jusqu&rsquo;\u00e0 pr\u00e9sent (<code>setAttributes()<\/code>par <code>onChange<\/code>exemple).<\/p>\n<p>\u00c0 l&rsquo;heure actuelle, notre code contient deux choses qui pourraient \u00eatre b\u00e9n\u00e9fiques pour passer aux fonctions\u00a0; <code>InspectorControls<\/code>et <code>BlockControls<\/code>. Cela raccourcira <code>return<\/code>consid\u00e9rablement notre et rendra notre code plus facile \u00e0 lire.<\/p>\n<p>Nous d\u00e9finissons deux fonctions qui renvoient le <code>InspectorControls<\/code>bloc entier et le <code>BlockControls<\/code>bloc entier. En utilisant les fonctions fl\u00e9ch\u00e9es (<code>functionName =() =&gt; { ... }<\/code>), nous avons un acc\u00e8s complet \u00e0 <code>this<\/code>pour obtenir des accessoires. Si vous n&rsquo;avez pas fait la derni\u00e8re partie de l&rsquo;\u00e9tape 1 &#8211; configurer Babel avec les syntaxes les plus r\u00e9centes, vous obtiendrez des erreurs de compilation. Vous devrez recourir \u00e0 la cr\u00e9ation d&rsquo;un constructeur et d&rsquo;une liaison <code>this<\/code>pour chaque fonction. Vous pouvez en savoir plus sur la manipulation <code>this<\/code>au d\u00e9but de <a href=\"https:\/\/reactjs.org\/docs\/faq-functions.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la page FAQ de React<\/a>.<\/p>\n<p>Rappelez-vous \u00e9galement que parce que nous sommes dans une classe maintenant, vous devez appeler toutes ses fonctions avec <code>this.<\/code>devant.<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n\u00a0\n    getInspectorControls =() =&gt; {\n        const { attributes, setAttributes } = this.props;\n\u00a0\n        return (&lt;InspectorControls&gt;\n                ...\n            &lt;\/InspectorControls&gt;\n        );\n    }\n\u00a0\n    getBlockControls = () =&gt; {\n        const { attributes, setAttributes } = this.props;\n\u00a0\n        return (&lt;BlockControls&gt;\n                ...\n            &lt;\/BlockControls&gt;\n        );\n    }\n\u00a0\n    render() {\n        const { attributes, setAttributes } = this.props;\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return ([\n            this.getInspectorControls(),\n            this.getBlockControls(),\n            &lt;div className={alignmentClass}&gt;\n                &lt;RichText \n                    tagName=\"h2\"\n                    placeholder=\"Write your heading here\"\n                    value={attributes.myRichHeading}\n                    onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                \/&gt;\n                &lt;RichText\n                    tagName=\"p\"\n                    placeholder=\"Write your paragraph here\"\n                    value={attributes.myRichText}\n                    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                \/&gt;\n            &lt;\/div&gt;\n        ]);\n    }\n}<\/code><\/pre>\n<p>Notez que j&rsquo;ai exclu le contenu r\u00e9el de <code>InspectorControls<\/code>et <code>BlockControls<\/code>pour garder le code plus court. Rien dans leur code ne doit changer.<\/p>\n<p>Nous utilisons \u00e9galement le fait que l&rsquo; <code>return<\/code>instruction peut \u00e9galement renvoyer un tableau. Tout dans le tableau sera rendu comme d&rsquo;habitude dans l&rsquo;ordre dans lequel ils se trouvent. Cela nous permet d&rsquo;appeler facilement des fonctions directement \u00e0 l&rsquo;int\u00e9rieur de l&rsquo; <code>return<\/code>instruction.<\/p>\n<p>Vous pouvez \u00e9videmment \u00e9galement d\u00e9finir des m\u00e9thodes de cycle de vie, telles que <code>componentDidMount()<\/code>. Il n&rsquo;y a aucune diff\u00e9rence \u00e0 faire cela dans les composants Gutenberg que dans React.<\/p>\n<h2>Constructeur et \u00e9tat d&rsquo;utilisation<\/h2>\n<p>Essayons d&rsquo;impl\u00e9menter l&rsquo;\u00e9tat dans notre composant. Gardez \u00e0 l&rsquo;esprit que l&rsquo;\u00e9tat n&rsquo;est que quelque chose de stock\u00e9 temporairement dans notre composant de classe et n&rsquo;est enregistr\u00e9 nulle part, comme dans les attributs. C&rsquo;est juste pour garder le contr\u00f4le de &#8211; enfin &#8211; l&rsquo;\u00e9tat de votre composant. Les utilisations courantes de l&rsquo;\u00e9tat consistent \u00e0 utiliser l&rsquo;\u00e9tat comme indicateur d&rsquo;\u00e9tat en attendant le retour d&rsquo;un appel asynchrone, \u00e0 conserver le score de quelque chose de temporaire avant de l&rsquo;enregistrer dans un attribut ou \u00e0 impl\u00e9menter des &quot;modes de pr\u00e9visualisation\/\u00e9dition&quot; de bloc.<\/p>\n<p>Vous vous r\u00e9f\u00e9rez \u00e0 l&rsquo;\u00e9tat et \u00e0 l&rsquo;\u00e9tat de mise \u00e0 jour comme dans React ; avec <code>this.state<\/code>et <code>setState()<\/code>. Normalement, vous initialisez l&rsquo;\u00e9tat dans le constructeur. Et en ce qui concerne la d\u00e9finition d&rsquo;un constructeur &#8211; c&rsquo;est exactement comme dans React &#8211; n&rsquo;oubliez pas de passer <code>props<\/code>et de faire <code>super(props)<\/code>aussi. Bref:<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n    constructor(props) {\n        super(props);\n\u00a0\n        this.state = {\n            example: 1\n        }\n    }\n\u00a0\n    render() {\n        this.setState({ example: 2 });\n        console.log(this.state.example);\n        ...<\/code><\/pre>\n<h3>Bascule d&rsquo;\u00e9dition\/d&rsquo;aper\u00e7u du mode bloc<\/h3>\n<p>Utilisons ce que nous avons appris \u00e0 l&rsquo;\u00e9tape pr\u00e9c\u00e9dente dans les barres d&rsquo;outils pour cr\u00e9er un &quot;s\u00e9lecteur de mode&quot; pour notre bloc. Nous impl\u00e9mentons une barre d&rsquo;outils avec un bouton qui bascule l&rsquo;\u00e9tat entre le mode aper\u00e7u et le mode \u00e9dition. En mode \u00e9dition, le bloc obtient les deux composants RichText comme d&rsquo;habitude. Mais lors du passage en mode aper\u00e7u, nous avons d\u00e9sactiv\u00e9 l&rsquo;\u00e9dition et rendu la sortie du bloc.<\/p>\n<p>Nous cr\u00e9ons d&rsquo;abord un constructeur et configurons l&rsquo;\u00e9tat avec une propri\u00e9t\u00e9 bool\u00e9enne ; <code>editMode<\/code>qui commence par <code>true<\/code>. Le <code>super(props)<\/code>est n\u00e9cessaire lors de la d\u00e9finition d&rsquo;un constructeur dans un composant React bas\u00e9 sur une classe.<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n    constructor(props) {\n        super(props);\n        this.state = {\n            editMode: true\n        }\n    }\n    ...<\/code><\/pre>\n<p>Dans notre fonction de sortie des barres d&rsquo;outils, nous modifions le bouton personnalis\u00e9 que nous avons cr\u00e9\u00e9 pr\u00e9c\u00e9demment (qui ne fait que <code>console.log<\/code>quelque chose en cliquant dessus). Sur sa <code>onClick<\/code>prop, nous appelons <code>setState()<\/code>et annulons la <code>editMode<\/code>valeur bool\u00e9enne actuelle. Pour faciliter la compr\u00e9hension de l&rsquo;utilisateur, nous basculons \u00e9galement entre l&rsquo;ic\u00f4ne et l&rsquo;\u00e9tiquette du bouton. Par exemple, lorsque le mode de pr\u00e9visualisation est actif, le bouton affiche l&rsquo;\u00e9tiquette &quot;Modifier&quot; et une ic\u00f4ne en forme de crayon qui est g\u00e9n\u00e9ralement acceptable comme modification.<\/p>\n<pre><code>getBlockControls = () =&gt; {\n    const { attributes, setAttributes } = this.props;\n    return (&lt;BlockControls&gt;\n            &lt;AlignmentToolbar\n                value={attributes.textAlignment}\n                onChange={(newalign) =&gt; setAttributes({ textAlignment: newalign })}\n            \/&gt;\n            &lt;Toolbar&gt;\n                &lt;IconButton\n                    label={ this.state.editMode? \"Preview\": \"Edit\" }\n                    icon={ this.state.editMode? \"format-image\": \"edit\" }\n                    onClick={() =&gt; this.setState({ editMode: !this.state.editMode })}\n                \/&gt;\n            &lt;\/Toolbar&gt;\n        &lt;\/BlockControls&gt;\n    );\n}<\/code><\/pre>\n<p>Et enfin, dans la m\u00e9thode de rendu principale de notre bloc, nous pouvons faire ce que nous voulons. Cette partie d\u00e9pend vraiment de vous &#8211; vous faites la m\u00eame chose que nous avons fait avec l&rsquo;\u00e9tiquette et l&rsquo;ic\u00f4ne sur le bouton ci-dessus. Nous ajoutons deux blocs de sortie, un if <code>this.state.editMode<\/code>is <code>true<\/code>(qui devrait \u00eatre les composants modifiables habituels <code>RichText<\/code>), et un autre if it&rsquo;s <code>false<\/code>.<\/p>\n<p>\u00c0 titre d&rsquo;exemple, j&rsquo;utilise deux composants WordPress de <code>wp.components<\/code>; <code>Placeholder<\/code>et <code>Disabled<\/code>pour le mode de pr\u00e9visualisation. Le <code>Placeholder<\/code>composant place votre bloc dans une jolie bo\u00eete grise, ce qui indique tr\u00e8s clairement qu&rsquo;il n&rsquo;est pas modifiable. Gardez \u00e0 l&rsquo;esprit qu&rsquo;il est livr\u00e9 avec un style, donc si vous vouliez un aper\u00e7u parfait, cela pourrait ne pas \u00eatre pour vous. Et <code>Disabled<\/code>j&rsquo;enveloppe \u00e9galement tout dans un composant qui rend tout \u00e0 l&rsquo;int\u00e9rieur non modifiable, non cliquable et non d\u00e9pla\u00e7able. Voici notre nouvelle <code>render()<\/code>fonction dans notre composant\u00a0:<\/p>\n<pre><code>const { ..., Fragment } = wp.element;\nconst {... Placeholder, Disabled } = wp.components;  \/\/ Don't forget to add these at the top\n\u00a0\n...\nrender() {\n    const { attributes, setAttributes } = this.props;\n    const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n    return ([\n        this.getInspectorControls(),\n        this.getBlockControls(),\n        &lt;div className={alignmentClass}&gt;\n            {this.state.editMode &amp;&amp; \n                &lt;Fragment&gt;\n                    &lt;RichText \n                        tagName=\"h2\"\n                        placeholder=\"Write your heading here\"\n                        value={attributes.myRichHeading}\n                        onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                    \/&gt;\n                    &lt;RichText\n                        tagName=\"p\"\n                        placeholder=\"Write your paragraph here\"\n                        value={attributes.myRichText}\n                        onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                    \/&gt;\n                &lt;\/Fragment&gt;\n            }\n            {!this.state.editMode &amp;&amp; \n                &lt;Placeholder isColumnLayout={true}&gt;\n                    &lt;Disabled&gt;\n                        &lt;RichText.Content \n                            tagName=\"h2\"\n                            value={attributes.myRichHeading}\n                        \/&gt;\n                        &lt;RichText.Content\n                            tagName=\"p\"\n                            value={attributes.myRichText}\n                        \/&gt;\n                    &lt;\/Disabled&gt;\n                &lt;\/Placeholder&gt;\n            }\n        &lt;\/div&gt;\n    ]);\n}\n...<\/code><\/pre>\n<p>J&rsquo;utilise \u00e9galement un composant <code>Fragment<\/code>( <code>wp.element<\/code>package) qui est le m\u00eame que <code>React.Fragment<\/code>. Si vous ne le connaissez pas, nous encapsulons la sortie \u00e0 l&rsquo;int\u00e9rieur lorsque nous ne voulons pas ajouter d&rsquo;encapsuleurs HTML suppl\u00e9mentaires inutiles. Dans React, tout doit avoir un n\u0153ud racine. Lorsque le mode d&rsquo;\u00e9dition est actif (ligne <code>#13<\/code>), nous produisons deux <code>RichText<\/code>composants l&rsquo;un apr\u00e8s l&rsquo;autre, nous avons donc besoin d&rsquo;un n\u0153ud racine autour d&rsquo;eux.<\/p>\n<p>Lorsque le mode aper\u00e7u est actif (ligne <code>#29<\/code>), nous affichons les <code>RichText<\/code>valeurs des deux composants. Comme nous le faisons dans <code>save<\/code>, nous utilisons <code>RichText.Content<\/code>pour renvoyer leurs valeurs au lieu du petit \u00e9diteur.<\/p>\n<p>Le composant <code>Placeholder<\/code>est disponible dans le style flex et par d\u00e9faut avec la ligne flex-direction. Fournir <code>true<\/code>dans l&rsquo;accessoire le <code>isColumnLayout<\/code>change en colonne flex-direction (donc tout s&#8217;empile). Mais comme mentionn\u00e9 pr\u00e9c\u00e9demment, vous voudrez peut-\u00eatre ignorer ce composant et plut\u00f4t g\u00e9n\u00e9rer votre aper\u00e7u exactement comme il le serait dans le frontend.<\/p>\n<p>Et avec cela, nous avons un basculeur de pr\u00e9visualisation\/\u00e9dition en mode bloc. \u00c9videmment, vous pouvez ajuster le contenu du &quot;mode d&rsquo;\u00e9dition&quot; pour afficher par exemple les entr\u00e9es de contr\u00f4le ou autres.<\/p>\n<\/p>\n<p>Vous pouvez cr\u00e9er autant de composants que vous le souhaitez, vous n&rsquo;\u00eates pas limit\u00e9 \u00e0 n&rsquo;en avoir qu&rsquo;un pour la <code>edit<\/code>fonction! Cr\u00e9ez simplement plus de composants et incluez-les dans une <code>return<\/code>d\u00e9claration. C&rsquo;est l&rsquo;id\u00e9e de React, en fait &#8211; construire des morceaux de code encapsul\u00e9s, chacun g\u00e9rant \u00e9ventuellement son propre \u00e9tat et les combinant pour cr\u00e9er des interfaces utilisateur complexes.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans cette partie de notre didacticiel sur les blocs Gutenberg, nous apprendrons comment d\u00e9placer la fonction d&rsquo;\u00e9dition de registerBlockType vers un composant s\u00e9par\u00e9 bas\u00e9 sur une classe.<\/p>\n","protected":false},"author":1,"featured_media":152941,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,893,717,717,832,936,936,1110,801,801,832,841,841,862,862],"tags":[1167],"class_list":{"0":"post-234228","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-code-2","9":"category-developpeur","11":"category-guide-pour-les-debutants","12":"category-gutenberg-3","14":"category-n-a","15":"category-php-3","18":"category-tutoriels","20":"category-wordpress-3","22":"tag-affiai-fr"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/234228","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/comments?post=234228"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/234228\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/152941"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=234228"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=234228"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=234228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}