{"id":233530,"date":"2023-02-17T10:23:00","date_gmt":"2023-02-17T07:23:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233530"},"modified":"2022-11-11T00:11:34","modified_gmt":"2022-11-10T21:11:34","slug":"skapa-anpassat-gutenberg-block-del-7-skapa-dina-egna-anpassade-komponenter","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/skapa-anpassat-gutenberg-block-del-7-skapa-dina-egna-anpassade-komponenter\/","title":{"rendered":"Skapa anpassat Gutenberg-block &#8211; Del 7: Skapa dina egna anpassade komponenter"},"content":{"rendered":"\n<p>Hittills i denna handledningsserie har vi skrivit all kod inuti <code>registerBlockType()<\/code>funktionen <code>edit<\/code>. Det \u00e4r fullt m\u00f6jligt och rekommenderas ofta att ist\u00e4llet tilldela redigering till en separat komponent. Genom att g\u00f6ra det kan vi anv\u00e4nda funktionalitet som komponenttillst\u00e5nd och livscykelmetoder. Den \u00e4r ocks\u00e5 mycket renare, l\u00e4sbar och ger \u00e5teranv\u00e4ndbar kod!<\/p>\n<p>Om du inte \u00e4r bekant med att skapa React-komponenter eller vad tillst\u00e5nd och livscykelmetoder \u00e4r, rekommenderar jag att du l\u00e4ser <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Reacts officiella guide om detta \u00e4mne<\/a> f\u00f6rst.<\/p>\n<h2>Definiera en klasskomponent f\u00f6r<code>edit<\/code><\/h2>\n<p>Du kan definiera en komponent antingen som en funktion eller en klass. Med en klasskomponent kan du anv\u00e4nda funktionalitet som till exempel tillst\u00e5nd och livscykelmetoder. Men i nyare React-versioner (16+) kan du anv\u00e4nda React-krokar f\u00f6r att simulera tillst\u00e5nd och livscykelmetoder inuti funktionskomponenter. Men i den h\u00e4r handledningen kommer vi att fokusera p\u00e5 att skapa en klasskomponent. Det vi har skapat hittills i den h\u00e4r serien, &quot;inline&quot; i <code>registerBlockType()<\/code>f\u00f6r <code>edit<\/code>och <code>save<\/code>, \u00e4r funktionskomponenter.<\/p>\n<p>F\u00f6r att definiera en klasskomponent ut\u00f6kar vi WordPress&#8217; <code>Component<\/code>(i <code>wp.element<\/code>paketet), precis som du skulle ut\u00f6ka en klasskomponent till <code>React.Component<\/code>.<\/p>\n<p>T\u00e4nk p\u00e5 att din klasskomponent m\u00e5ste inneh\u00e5lla funktionen <code>render()<\/code>. Och p\u00e5 grund av hur Javascript fungerar m\u00e5ste din klass definieras f\u00f6re ditt <code>registerBlockType()<\/code>samtal (skriv din klasskomponent f\u00f6rst i filen och beh\u00e5ll <code>registerBlockType()<\/code>efter den. Senare i det h\u00e4r inl\u00e4gget kommer vi att l\u00e4ra oss hur du separerar komponenter i separata filer, exporterar och inkluderar dem).<\/p>\n<p>Kort sagt, s\u00e5h\u00e4r:<\/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>Rekvisitan fr\u00e5n <code>edit<\/code>appliceras automatiskt p\u00e5 v\u00e5r komponent. Gl\u00f6m inte att en klasskomponent du beh\u00f6ver h\u00e4nvisa till rekvisita med <code>this.props<\/code>. Det \u00e4r vanligt i WordPress Gutenberg core att anv\u00e4nda separata komponenter f\u00f6r <code>edit<\/code>funktionerna d\u00e5 de oftast inneh\u00e5ller mycket mer kod. Funktionen <code>save<\/code>kan ofta l\u00e4mnas kvar <code>registerBlockType()<\/code>om den inte inneh\u00e5ller mycket kod ocks\u00e5.<\/p>\n<p>Genom att g\u00f6ra detta kan du nu skriva din komponent precis som du skulle g\u00f6ra med React. Du kan l\u00e4gga till funktioner, konstrukt\u00f6r, tillst\u00e5nd och livscykelmetoder.<\/p>\n<p>Det h\u00e4r \u00e4r koden vi hamnade i det sista steget, omvandlad till en klasskomponent:<\/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>Om du destrukturerade <code>attributes<\/code>och <code>setAttributes<\/code>fr\u00e5n rekvisita som vi gjorde, \u00e4r allt du beh\u00f6ver \u00e4ndra n\u00e4r du flyttar till en separat klasskomponent att \u00e4ndra en rad; <code>#9<\/code>fr\u00e5n <code>props<\/code>till <code>this.props<\/code>. All kod kommer att fungera precis som tidigare utan att fixa n\u00e5got annat. Det \u00e4r det fina med att f\u00f6rst\u00f6ra. Om du inte destrukturerade det och h\u00e4nvisade till t.ex. <code>props.attributes<\/code>direkt, skulle du beh\u00f6va l\u00e4gga <code>this.<\/code>till framf\u00f6r alla individuella referenser till <code>attributes<\/code>och <code>setAttributes<\/code>\u00f6verallt.<\/p>\n<p>L\u00e5t oss b\u00f6rja g\u00f6ra saker vi nu kan g\u00f6ra med en klasskomponent!<\/p>\n<h2>Definiera funktioner och<code>this<\/code><\/h2>\n<p>Visst, ja, du kan definiera funktioner inifr\u00e5n <code>edit<\/code>funktionskomponenten innan du anropar <code>return<\/code>. Men personligen har jag alltid f\u00f6redragit att separera funktionalitet med logik. Jag tycker att det \u00e4r b\u00e4ttre att separera funktioner f\u00f6r logik och andra \u00e4ndam\u00e5l utanf\u00f6r funktionen som \u00e4r ansvarig f\u00f6r att rendera utdata. Vissa m\u00e4nniskor f\u00f6redrar ocks\u00e5 att anropa funktioner i h\u00e4ndelser, ist\u00e4llet f\u00f6r att g\u00f6ra dem inline som vi har gjort hittills (g\u00f6r <code>setAttributes()<\/code>till <code>onChange<\/code>exempel).<\/p>\n<p>Just nu har v\u00e5r kod tv\u00e5 saker som kan vara f\u00f6rdelaktiga f\u00f6r att flytta ut till funktioner; <code>InspectorControls<\/code>och <code>BlockControls<\/code>. Detta kommer att f\u00f6rkorta v\u00e5r <code>return<\/code>avsev\u00e4rt och g\u00f6ra v\u00e5r kod l\u00e4ttare att l\u00e4sa.<\/p>\n<p>Vi definierar tv\u00e5 funktioner som returnerar hela <code>InspectorControls<\/code>blocket och hela <code>BlockControls<\/code>blocket. Genom att anv\u00e4nda pilfunktioner (<code>functionName =() =&gt; { ... }<\/code>) har vi full tillg\u00e5ng till <code>this<\/code>f\u00f6r att f\u00e5 tag p\u00e5 rekvisita. Om du inte gjorde den sista delen av steg 1 \u2013 att st\u00e4lla in Babel med de senaste syntaxerna, kommer du att f\u00e5 kompileringsfel. Du m\u00e5ste tillgripa att skapa en konstruktor och bindning <code>this<\/code>f\u00f6r varje funktion. Du kan l\u00e4sa mer om hantering <code>this<\/code>i b\u00f6rjan av <a href=\"https:\/\/reactjs.org\/docs\/faq-functions.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Reacts FAQ-sida<\/a>.<\/p>\n<p>Kom ocks\u00e5 ih\u00e5g att eftersom vi \u00e4r i en klass nu m\u00e5ste du anropa alla dess funktioner med <code>this.<\/code>framf\u00f6r.<\/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>Observera att jag har uteslutit det faktiska inneh\u00e5llet i <code>InspectorControls<\/code>och <code>BlockControls<\/code>f\u00f6r att h\u00e5lla koden kortare. Ingenting i deras kod beh\u00f6ver \u00e4ndras.<\/p>\n<p>Vi anv\u00e4nder ocks\u00e5 det faktum att <code>return<\/code>uttalandet ocks\u00e5 kan returnera en array. Allt i arrayen kommer att renderas som vanligt i den ordning de \u00e4r i. Detta g\u00f6r det enkelt f\u00f6r oss att anropa funktioner direkt inuti <code>return<\/code>satsen.<\/p>\n<p>Du kan sj\u00e4lvklart ocks\u00e5 definiera livscykelmetoder, som <code>componentDidMount()<\/code>. Det \u00e4r ingen skillnad p\u00e5 att g\u00f6ra dessa i Gutenberg-komponenter \u00e4n i React.<\/p>\n<h2>Konstrukt\u00f6r och anv\u00e4nder tillst\u00e5nd<\/h2>\n<p>L\u00e5t oss f\u00f6rs\u00f6ka implementera tillst\u00e5nd i v\u00e5r komponent. T\u00e4nk p\u00e5 att tillst\u00e5nd bara \u00e4r n\u00e5got som lagras tillf\u00e4lligt i v\u00e5r klasskomponent och inte sparas n\u00e5gonstans \u2013 till exempel i attribut. Det \u00e4r bara f\u00f6r att ha kontroll \u00f6ver \u2013 ja \u2013 tillst\u00e5ndet f\u00f6r din komponent. Vanliga anv\u00e4ndningar av tillst\u00e5nd \u00e4r att anv\u00e4nda tillst\u00e5nd som en statusflagga i v\u00e4ntan p\u00e5 att ett asynkront samtal ska \u00e5terkomma, att h\u00e5lla po\u00e4ngen f\u00f6r n\u00e5got tillf\u00e4lligt innan det sparas i ett attribut, eller att implementera blocket &quot;f\u00f6rhandsgransknings-\/redigeringsl\u00e4gen&quot;.<\/p>\n<p>Du refererar till tillst\u00e5nd och uppdateringstillst\u00e5nd precis som i React; med <code>this.state<\/code>och <code>setState()<\/code>. Normalt skulle du initialisera tillst\u00e5ndet i konstruktorn. Och n\u00e4r det g\u00e4ller att definiera en konstrukt\u00f6r \u2013 det \u00e4r precis som i React \u2013 gl\u00f6m inte att passera <code>props<\/code>och g\u00f6ra det <code>super(props)<\/code>ocks\u00e5. Kortfattat:<\/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>V\u00e4xlare f\u00f6r redigering\/f\u00f6rhandsvisning av blockl\u00e4ge<\/h3>\n<p>L\u00e5t oss anv\u00e4nda det vi l\u00e4rde oss i f\u00f6reg\u00e5ende steg i Verktygsf\u00e4lt f\u00f6r att skapa en &quot;l\u00e4gesv\u00e4xlare&quot; f\u00f6r v\u00e5rt block. Vi implementerar ett verktygsf\u00e4lt med en knapp som v\u00e4xlar mellan f\u00f6rhandsgransknings- och redigeringsl\u00e4ge. I redigeringsl\u00e4ge f\u00e5r blocket de tv\u00e5 RichText-komponenterna som vanligt. Men n\u00e4r vi bytte till f\u00f6rhandsgranskningsl\u00e4ge inaktiverade vi redigering och renderade blockutg\u00e5ngen.<\/p>\n<p>F\u00f6rst skapar vi en konstruktor och st\u00e4ller in tillst\u00e5nd med en boolesk egenskap; <code>editMode<\/code>som b\u00f6rjar som <code>true<\/code>. Detta <code>super(props)<\/code>\u00e4r n\u00f6dv\u00e4ndigt n\u00e4r man definierar en konstruktor i en klassbaserad React-komponent.<\/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>I v\u00e5r funktion f\u00f6r att mata ut verktygsf\u00e4lten \u00e4ndrar vi den anpassade knappen vi skapade tidigare (vilket bara \u00e4r <code>console.log<\/code>n\u00e5got n\u00e4r man klickar p\u00e5 den). P\u00e5 dess <code>onClick<\/code>rekvisita kallar vi <code>setState()<\/code>och f\u00f6rnekar det nuvarande <code>editMode<\/code>booleska v\u00e4rdet. F\u00f6r att g\u00f6ra det l\u00e4ttare f\u00f6r anv\u00e4ndaren att f\u00f6rst\u00e5 v\u00e4xlar vi ocks\u00e5 mellan knappens ikon och etikett. T.ex. n\u00e4r f\u00f6rhandsgranskningsl\u00e4get \u00e4r aktivt visar knappen etiketten &quot;Redigera&quot; och en pennikon som vanligtvis accepteras som redigering.<\/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>Och slutligen inom huvudrenderingsmetoden f\u00f6r v\u00e5rt block, kan vi g\u00f6ra vad vi vill. Den h\u00e4r delen \u00e4r verkligen upp till dig \u2013 du g\u00f6r samma sak som vi gjorde med etiketten och ikonen p\u00e5 knappen ovan. Vi l\u00e4gger till tv\u00e5 utdatablock, ett om <code>this.state.editMode<\/code>\u00e4r <code>true<\/code>(som borde vara de vanliga redigerbara <code>RichText<\/code>komponenterna), och ett annat om det \u00e4r <code>false<\/code>.<\/p>\n<p>Som ett exempel anv\u00e4nder jag tv\u00e5 WordPress-komponenter fr\u00e5n <code>wp.components<\/code>; <code>Placeholder<\/code>och <code>Disabled<\/code>f\u00f6r f\u00f6rhandsgranskningsl\u00e4get. Komponenten <code>Placeholder<\/code>l\u00e4gger ditt block i en snygg gr\u00e5 ruta som g\u00f6r det riktigt tydligt att det inte g\u00e5r att redigera. T\u00e4nk p\u00e5 att den kommer med styling s\u00e5 om du ville ha en perfekt f\u00f6rhandsvisning kanske det inte \u00e4r n\u00e5got f\u00f6r dig. Och jag lindar ocks\u00e5 allt inuti en <code>Disabled<\/code>komponent som g\u00f6r allt inuti oredigerbart, oklickbart och odragbart. Detta \u00e4r v\u00e5r nya <code>render()<\/code>funktion i v\u00e5r komponent:<\/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>Jag anv\u00e4nder ocks\u00e5 en komponent <code>Fragment<\/code>( <code>wp.element<\/code>paket) som \u00e4r samma som <code>React.Fragment<\/code>. Om du inte \u00e4r bekant med det l\u00e4gger vi in \u200b\u200butdata i det n\u00e4r vi inte vill l\u00e4gga till extra on\u00f6diga HTML-omslag. I React m\u00e5ste allt ha en rotnod. N\u00e4r redigeringsl\u00e4get \u00e4r aktivt (line <code>#13<\/code>) matar vi ut tv\u00e5 <code>RichText<\/code>komponenter direkt efter varandra, s\u00e5 vi beh\u00f6ver en rotnod runt dem.<\/p>\n<p>N\u00e4r f\u00f6rhandsgranskningsl\u00e4get \u00e4r aktivt (rad <code>#29<\/code>) matar vi ut de tv\u00e5 <code>RichText<\/code>komponenternas v\u00e4rden. Som vi g\u00f6r i <code>save<\/code>, anv\u00e4nder vi <code>RichText.Content<\/code>f\u00f6r att returnera deras v\u00e4rden ist\u00e4llet f\u00f6r den lilla redigeraren.<\/p>\n<p>Komponenten <code>Placeholder<\/code>kommer i flex styling och som standard med flex-direction rad. Att tillhandah\u00e5lla <code>true<\/code>i rekvisitan <code>isColumnLayout<\/code>\u00e4ndrar den till flex-direction-kolumn (s\u00e5 att allt staplas). Men som n\u00e4mnts tidigare \u2013 du kanske vill hoppa \u00f6ver den h\u00e4r komponenten och hellre generera din f\u00f6rhandsvisning precis som den skulle vara i frontend.<\/p>\n<p>Och med det har vi en v\u00e4xlare f\u00f6r f\u00f6rhandsvisning\/redigering av blockl\u00e4ge. Sj\u00e4lvklart kan du justera inneh\u00e5llet i &quot;redigeringsl\u00e4get&quot; f\u00f6r att visa t.ex. kontrolling\u00e5ngar eller liknande.<\/p>\n<\/p>\n<p>Du kan skapa s\u00e5 m\u00e5nga komponenter du vill, du \u00e4r inte begr\u00e4nsad till att bara ha en f\u00f6r <code>edit<\/code>funktionen! Skapa helt enkelt fler komponenter och inkludera dem i ett <code>return<\/code>uttalande. Det \u00e4r id\u00e9n med React, faktiskt \u2013 att bygga inkapslade kodbitar, m\u00f6jligen hantera sina egna tillst\u00e5nd och kombinera dem f\u00f6r att g\u00f6ra komplexa anv\u00e4ndargr\u00e4nssnitt.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I den h\u00e4r delen av v\u00e5r Gutenberg-blockhandledning kommer vi att l\u00e4ra oss hur man flyttar ut registerBlockTypes redigeringsfunktion till en separat klassbaserad komponent.<\/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":[901,724,838,942,942,848,901,1110,807,807,838,848,724,868,868],"tags":[1173],"class_list":{"0":"post-233530","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-koda","8":"category-utvecklaren","9":"category-guide-foer-nyboerjare","10":"category-gutenberg-9","12":"category-handledningar","14":"category-n-a","15":"category-php-9","20":"category-wordpress-9","22":"tag-affiai-sv"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/233530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=233530"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/233530\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/152941"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=233530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=233530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=233530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}