{"id":233951,"date":"2023-02-26T18:20:00","date_gmt":"2023-02-26T15:20:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233951"},"modified":"2023-02-26T18:20:49","modified_gmt":"2023-02-26T15:20:49","slug":"gutenberg-aktualizowanie-withselect-i-withdispatch-do-hookow-react-useselect-i-usedispatch","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/gutenberg-aktualizowanie-withselect-i-withdispatch-do-hookow-react-useselect-i-usedispatch\/","title":{"rendered":"Gutenberg: Aktualizowanie withSelect i withDispatch do hook\u00f3w React (useSelect i useDispatch)"},"content":{"rendered":"\n<p>Ten post jest szybkim wprowadzeniem do sposobu, aby Tw\u00f3j kod Gutenberga by\u0142 zgodny z aktualnymi standardami za pomoc\u0105 hak\u00f3w React. Zobaczymy, jak to jest korzystne, dlaczego powinni\u015bmy to robi\u0107 i jak.<\/p>\n<h2>Co, haki?<\/h2>\n<p>Zak\u0142adam, \u017ce masz ju\u017c pewne do\u015bwiadczenie w pracy z nieco bardziej z\u0142o\u017conymi blokami lub wtyczkami Gutenberga, kt\u00f3re wysy\u0142aj\u0105 zapytania do post\u00f3w lub pobieraj\u0105 i aktualizuj\u0105 meta post\u00f3w. I w ten spos\u00f3b pracowa\u0142em z <code>[withSelect](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#withSelect)<\/code>i\/lub <code>[withDispatch](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#withDispatch)<\/code>. S\u0105 to komponenty wy\u017cszego rz\u0119du w WordPressie, kt\u00f3re umo\u017cliwiaj\u0105 dost\u0119p do sklep\u00f3w WordPressa w celu pobrania lub wypchni\u0119cia informacji, kt\u00f3re nieco wykraczaj\u0105 poza \u201enormalny&quot; blok lub edycj\u0119 post\u00f3w. Prawdopodobnie zosta\u0142e\u015b r\u00f3wnie\u017c zmuszony do u\u017cycia <code>compose<\/code>w celu po\u0142\u0105czenia swoich komponent z wieloma komponentami wy\u017cszego rz\u0119du. Je\u015bli Tw\u00f3j kod u\u017cywa tych wzorc\u00f3w, nie martw si\u0119 \u2013 dzia\u0142aj\u0105 doskonale i b\u0119d\u0105 dzia\u0142a\u0107 nadal! Ale w miar\u0119 rozwoju technologii mo\u017cemy dzia\u0142a\u0107 lepiej.<\/p>\n<p>Na pocz\u0105tku 2019 r. <a href=\"https:\/\/reactjs.org\/docs\/hooks-intro.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">React wypu\u015bci\u0142 hooki<\/a> (wersja 16.8) \u2013 kt\u00f3re pozwalaj\u0105 u\u017cywa\u0107 stanu bez u\u017cycia klasy i ulepsza\u0107 inne funkcje, co daje bardziej czytelny i wielokrotnego u\u017cytku kod. Na przyk\u0142ad usuni\u0119cie konieczno\u015bci pakowania kodu w komponenty wy\u017cszego rz\u0119du w celu uzyskania dost\u0119pu do rejestr\u00f3w. A <a href=\"https:\/\/make.wordpress.org\/core\/2019\/06\/10\/introducing-usedispatch-and-useselect\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">latem 2019 pojawi\u0142 si\u0119 WordPress<\/a>, uruchamiaj\u0105c niestandardowe hooki: <code>[useDispatch](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#useDispatch)<\/code>i <code>[useSelect](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#useSelect)<\/code>.<\/p>\n<p>Zalet haczyk\u00f3w jest wiele. Najcz\u0119stszym przyk\u0142adem jest umo\u017cliwienie korzystania ze stanu komponentu bez konieczno\u015bci pisania klasy JavaScript (<code>useState<\/code>). Ale moim zdaniem najwi\u0119ksz\u0105 zalet\u0105 jest mo\u017cliwo\u015b\u0107 ponownego u\u017cycia. Eliminuj\u0105c konieczno\u015b\u0107 u\u017cywania wzorc\u00f3w, takich jak rekwizyty renderowania i komponenty wy\u017cszego rz\u0119du, komponenty mog\u0105 by\u0107 zapisywane w znacznie bardziej niezale\u017cnych fragmentach. Kolejn\u0105 zalet\u0105 hook\u00f3w jest to, \u017ce tw\u00f3j kod jest \u0142atwiejszy do odczytania i zrozumienia!<\/p>\n<p>Przejd\u017amy od razu do kilku przyk\u0142ad\u00f3w i zobaczmy, jak zaimplementowa\u0107 <code>useSelect<\/code>i <code>useDispatch<\/code>zahaczy\u0107 w naszym kodzie!<\/p>\n<h2>Realizowanie<code>useSelect<\/code><\/h2>\n<p>Zacznijmy od <code>withSelect<\/code>i odpowiadaj\u0105cego mu haka <code>useSelect<\/code>. S\u0105 one u\u017cywane do pobierania w\u0142a\u015bciwo\u015bci wywodz\u0105cych si\u0119 ze stanu z zarejestrowanych selektor\u00f3w. Typowe przyk\u0142ady to dost\u0119p do selektor\u00f3w \u201e <code>core<\/code>&#8221; lub \u201e <code>core\/editor<\/code>&#8221; w celu wykonania zapyta\u0144 o posty (<code>getEntityRecords<\/code>), dost\u0119p do meta postu (<code>getEditedPostAttribute<\/code>) lub po prostu uzyskanie bie\u017c\u0105cego typu posta lub innych informacji.<\/p>\n<p>W celach demonstracyjnych zaczn\u0119 od prostego przyk\u0142adu. Za\u0142\u00f3\u017cmy, \u017ce mam komponent blokowy, w kt\u00f3rym mam gdzie\u015b selektor post\u00f3w. Aby uzupe\u0142ni\u0107 list\u0119 wpis\u00f3w, musz\u0119 uzyska\u0107 dost\u0119p do rejestru \u201e <code>core<\/code>&#8221; i wykona\u0107 <code>GetEntityRecords()<\/code>po\u0142\u0105czenie.<\/p>\n<h3>Stary spos\u00f3b przy u\u017cyciu<code>withSelect<\/code><\/h3>\n<p>Je\u015bli chc\u0119 kwestionowa\u0107 posty w bloku, musia\u0142bym zawin\u0105\u0107 m\u00f3j sk\u0142adnik w <code>withSelect<\/code>. Zwykle robi si\u0119 to w <code>export<\/code>o\u015bwiadczeniu.<\/p>\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce ten przyk\u0142ad kodu nie jest kompletny jako prawdziwy blok funkcjonalny lub wtyczka JS, zosta\u0142 usuni\u0119ty, aby pokaza\u0107 podstawowe koncepcje <code>withSelect<\/code>. Je\u015bli szukasz praktycznych przyk\u0142ad\u00f3w kodu, mam inne artyku\u0142y, kt\u00f3re to opisuj\u0105: np. <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/utworz-niestandardowy-blok-gutenberga-czesc-10-pobieranie-postow-i-komponentow-wyzszego-rzedu\/\" title=\"jak zaimplementowa\u0107 bloki z opcj\u0105 post select\">jak zaimplementowa\u0107 bloki z opcj\u0105 post select<\/a> lub <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/jak-dodac-pola-post-meta-do-paska-bocznego-dokumentu-gutenberg\/\" title=\"jak doda\u0107 meta post do inspektora\">jak doda\u0107 meta post do inspektora<\/a>. Te s\u0105 napisane za pomoc\u0105 <code>withSelect<\/code>i <code>withDispatch<\/code>, wi\u0119c zr\u00f3b to, a nast\u0119pnie wr\u00f3\u0107 tutaj, aby dowiedzie\u0107 si\u0119, jak przekszta\u0142ci\u0107 je w haki.<\/p>\n<pre><code>const { withSelect } = wp.data;\n\u00a0\nconst AWP_Example_Plugin = ({ somePosts }) =&gt; {\n    console.log(\"Posts from withSelect = \", somePosts);\n    return(\n        &lt;div&gt;\n            ...\n        &lt;\/div&gt;\n    );\n}\n\u00a0\nexport default withSelect( (select) =&gt; {      \n    return {\n        somePosts: select( 'core' ).getEntityRecords( 'postType', 'page' ),\n    };\n}) (AWP_Example_Plugin );<\/code><\/pre>\n<p>Jak wida\u0107 w linii <code>#12-16<\/code>, owijam sw\u00f3j komponent za pomoc\u0105 <code>withSelect<\/code>. Wewn\u0105trz funkcji withSelect mog\u0119 uzyska\u0107 dost\u0119p do sklepu, kt\u00f3ry chc\u0119, i zwracam zapytanie o post w rekwizycie \u201e <code>somePosts<\/code>&#8222;. Ta podpora b\u0119dzie wtedy dost\u0119pna w moim <code>AWP_Example_Plugin<\/code>komponencie (jak wida\u0107, zdestrukturyzowa\u0142em <code>somePosts<\/code>z podp\u00f3r w wierszu <code>#3<\/code>).<\/p>\n<p>Jak wspomniano wcze\u015bniej, ta metoda dzia\u0142a dobrze \u2013 i b\u0119dzie to robi\u0107 nadal. Ale ma to kilka wad. Po pierwsze, nie jest to \u0142atwe do zrozumienia. Jasne, to by\u0142 bardzo prosty przyk\u0142ad. Na pierwszy rzut oka na sam komponent nie masz pewno\u015bci, sk\u0105d <code>somePosts<\/code>pochodzi rekwizyt lub co to jest. Musisz wiedzie\u0107, aby poszuka\u0107 instrukcji eksportu i sprawdzi\u0107, czy s\u0105 jakie\u015b opakowania. Czuje si\u0119 te\u017c troch\u0119 chaotyczny. Wykonujesz znaczn\u0105 cz\u0119\u015b\u0107 wa\u017cnej pracy poza swoim komponentem, aby uzyska\u0107 co\u015b, co naprawd\u0119 chcesz, aby by\u0142o dost\u0119pne w twoim komponencie.<\/p>\n<p>Zr\u00f3bmy to lepiej za pomoc\u0105 hak\u00f3w.<\/p>\n<h3>Konwersja na<code>useSelect<\/code><\/h3>\n<p>Konwersja a <code>withSelect<\/code>na <code>useSelect<\/code>jest tak prosta, jak to tylko mo\u017cliwe. Pierwszym krokiem jest zdefiniowanie zmiennej <code>somePosts<\/code>wewn\u0105trz naszego komponentu, a nie na zewn\u0105trz przez <code>export<\/code>instrukcj\u0119. Drugim krokiem jest przeniesienie ca\u0142ej funkcji, kt\u00f3r\u0105 mieli\u015bmy <code>withSelect<\/code>do <code>useSelect<\/code>. I to wszystko.<\/p>\n<pre><code>const { useSelect } = wp.data;\n\u00a0\nconst AWP_Example_Plugin =() =&gt; {\n    const { somePosts } = useSelect( (select) =&gt; {        \n        return {\n            somePosts: select( 'core' ).getEntityRecords( 'postType', 'page' ),\n        };\n    } );\n    console.log(\"Posts from useSelect = \", somePosts);\n    return(\n        &lt;div&gt;\n            ...\n        &lt;\/div&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>Powy\u017cszy kod daje dok\u0142adnie taki sam wynik jak ten z <code>withSelect<\/code>. R\u00f3\u017cnica polega na tym, \u017ce kod jest teraz znacznie bardziej zrozumia\u0142y! Mo\u017cemy teraz bardzo \u0142atwo zobaczy\u0107, \u017ce zmienna <code>somePosts<\/code>przechowuje wynik zapytania post, bezpo\u015brednio w naszym komponencie.<\/p>\n<p><strong>Wa\u017cna uwaga<\/strong>: <code>useSelect<\/code>akceptuje drugi parametr; szereg zale\u017cno\u015bci. Zale\u017cno\u015bci to zmienne, kt\u00f3re zapewniaj\u0105, \u017ce uruchamiamy si\u0119 tylko wtedy, <code>useSelect<\/code>gdy zmieni si\u0119 jedna z zale\u017cno\u015bci (warto\u015bci zmiennych). Ten fragment jest wa\u017cniejszy <code>useDispatch<\/code>ni\u017c tutaj, wi\u0119c wyja\u015bni\u0119 to nieco dalej w <code>useDispatch<\/code>sekcji poni\u017cej.<\/p>\n<h2>Realizowanie<code>useDispatch<\/code><\/h2>\n<p>Przyjrzyjmy si\u0119 teraz <code>withDispatch<\/code>i odpowiadaj\u0105cemu mu hakowi <code>useDispatch<\/code>. S\u0142u\u017c\u0105 do wysy\u0142ania rekwizyt\u00f3w do rejestr\u00f3w. Na przyk\u0142ad m\u00f3wi\u0105c Gutenbergowi, aby zaktualizowa\u0142 meta postu za pomoc\u0105 \u201e <code>core\/editor<\/code>&#8222;.<\/p>\n<p>Ponownie, dla cel\u00f3w demonstracyjnych, moje przyk\u0142ady kodu nie s\u0105 kompletnymi funkcjonalnymi fragmentami kodu \u2013 ilustruj\u0105 tylko cz\u0119\u015bci dotycz\u0105ce tych wzorc\u00f3w. W tym przyk\u0142adzie zak\u0142adam, \u017ce mam pole tekstowe pokazuj\u0105ce meta postu &#8211; i chc\u0119 zaktualizowa\u0107 warto\u015b\u0107 meta postu po zmianie.<\/p>\n<h3>Stary spos\u00f3b przy u\u017cyciu<code>withDispatch<\/code><\/h3>\n<p>Poniewa\u017c <code>withDispatch<\/code>jest to komponent wy\u017cszego rz\u0119du, musia\u0142bym owin\u0105\u0107 w to m\u00f3j komponent. Zwykle robi si\u0119 to w <code>export<\/code>o\u015bwiadczeniu. Aby pole tekstowe dla naszej meta dzia\u0142a\u0142o,<\/p>\n<p>Na przyk\u0142ad:<\/p>\n<pre><code>const { withDispatch } = wp.data;\nconst { __ } = wp.i18n;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\nconst AWP_Example_Plugin = ({ setPostMeta }) =&gt; { \n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'withDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value=\"\"\n                    onChange={ (value) =&gt; setPostMeta( { example_post_meta: value }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default withDispatch( (dispatch) =&gt; {\n    return {\n        setPostMeta( newMeta) {\n            dispatch( 'core\/editor' ).editPost( { meta: newMeta } );\n        }\n    };\n} )( AWP_Example_Plugin );<\/code><\/pre>\n<p>W wierszu <code>#20-26<\/code>zawijamy komponent do \u015brodka <code>withDispatch<\/code>, w kt\u00f3rym zwracamy funkcj\u0119 \u201e <code>setPostMeta<\/code>&#8222;, kt\u00f3ra wysy\u0142a meta posta (aby j\u0105 zaktualizowa\u0107). W wierszu <code>#6<\/code>destrukturyzujemy podp\u00f3rk\u0119, aby mo\u017cna by\u0142o jej u\u017cy\u0107 w zdarzeniu pola tekstowego <code>onChange<\/code>w wierszu <code>#13<\/code>. (Pami\u0119taj, \u017ce powy\u017cszy przyk\u0142ad nie b\u0119dzie dzia\u0142a\u0142, poniewa\u017c ustawili\u015bmy warto\u015b\u0107 pola tekstowego na pusty ci\u0105g. To tylko po to, aby zademonstrowa\u0107, jak u\u017cyjemy wysy\u0142ki).<\/p>\n<p>Ponownie widzimy, \u017ce kod nie jest tak prosty do zrozumienia. Musia\u0142by\u015b wiedzie\u0107, jak poszuka\u0107 opakowania, aby dowiedzie\u0107 si\u0119, z czego rekwizyt \u201e <code>setPostMeta<\/code>&#8221; jest lub z kt\u00f3rego pochodzi. Zr\u00f3bmy to lepiej za pomoc\u0105 hak\u00f3w!<\/p>\n<h3>Konwersja na<code>useDispatch<\/code><\/h3>\n<p>Zmiana <code>withDispatch<\/code>na <code>useDispatch<\/code>nie jest tak prosta, jak <code>withSelect<\/code>na <code>useSelect<\/code>. Jednak nadal jest to do\u015b\u0107 \u0142atwe. Nale\u017cy pami\u0119ta\u0107 o dw\u00f3ch rzeczach. Jednym z nich jest to, \u017ce <code>useDispatch<\/code>jako pierwszy parametr przyjmuje nazw\u0119 sklepu. <code>onChange<\/code>Uzyskaliby\u015bmy wtedy dost\u0119p do sklepu i wywo\u0142aliby\u015bmy jego dost\u0119pne funkcje, gdy z niego korzystamy (np. w zdarzeniu pola tekstowego ). Po drugie, tablica zale\u017cno\u015bci od <code>useDispatch<\/code>drugiego parametru jest wa\u017cniejsza ni\u017c z <code>useSelect<\/code>. Mo\u017cesz ryzykowa\u0107, \u017ce kod sko\u0144czy si\u0119 w niesko\u0144czonej p\u0119tli, je\u015bli nie b\u0119dziesz prawid\u0142owo zarz\u0105dza\u0107 zale\u017cno\u015bciami. Dopiero po zmianie zmiennych zale\u017cno\u015bci skrypt zostanie ponownie uruchomiony <code>useDispatch<\/code>.<\/p>\n<p>Na przyk\u0142ad:<\/p>\n<pre><code>const { useDispatch } = wp.data;\nconst { __ } = wp.i18n;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\nconst AWP_Example_Plugin =() =&gt; {  \n    const tmpMetaValue = \"\";\n    const { editPost } = useDispatch( 'core\/editor', [ tmpMetaValue ] );\n\u00a0\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'useDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ tmpMetaValue }\n                    onChange={ (value) =&gt; editPost( { meta: { example_post_meta: value } }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>Na linii <code>#8<\/code>destrukujemy to, czego potrzebujemy od sklepu &#8217; <code>core\/editor<\/code>&#8217;. Interesuje nas tylko <code>editPost<\/code>funkcja, kt\u00f3rej mo\u017cemy u\u017cy\u0107 do aktualizacji postu meta. Jako drugi parametr <code>useDispatch<\/code>podajemy zale\u017cno\u015bci. Je\u015bli chodzi o przyk\u0142ad aktualizacji meta postu, u\u017cycie warto\u015bci meta posta (za pomoc\u0105 <code>useSelect<\/code>) by\u0142oby idealne jako zale\u017cno\u015b\u0107. W tym przyk\u0142adzie ustawi\u0142em j\u0105 jako zmienn\u0105 fikcyjn\u0105. Poszukaj bardziej kompletnego i realistycznego przyk\u0142adu. A nast\u0119pnie w wierszu zdarzenia <code>#16<\/code>pola tekstowego <code>onChange<\/code>wywo\u0142ujemy <code>editPost<\/code>aktualizacj\u0119 meta. Zwr\u00f3\u0107 uwag\u0119 na r\u00f3\u017cnic\u0119 w tej linii z u\u017cyciem <code>withDispatch<\/code>powy\u017cej! Poniewa\u017c u\u017cywamy <code>editPost<\/code>bezpo\u015brednio zamiast zwraca\u0107 funkcj\u0119 do aktualizacji meta postu dla nas (<code>setPostMeta<\/code>), musimy dostarczy\u0107 obiekt z<code>meta<\/code>jako klucz, a nast\u0119pnie obiekt z meta postu, kt\u00f3ry chcemy zaktualizowa\u0107. Podzielili\u015bmy <code>withDispatch<\/code>kod na kawa\u0142ki.<\/p>\n<p>Mimo to u\u017cycie <code>useDispatch<\/code>sprawia, \u017ce \u200b\u200bkod jest znacznie bardziej czytelny i zrozumia\u0142y. Koniec z dodawaniem kodu poza naszym komponentem, kt\u00f3rego musimy u\u017cy\u0107 wewn\u0105trz.<\/p>\n<h2>Pe\u0142niejszy przyk\u0142ad i eliminacja potrzeby<code>compose<\/code><\/h2>\n<p>S\u0105 szanse, \u017ce je\u015bli u\u017cywasz <code>withDispatch<\/code>, b\u0119dziesz potrzebowa\u0107 <code>withSelect<\/code>r\u00f3wnie\u017c tego komponentu. W powy\u017cszych przyk\u0142adach do konwersji <code>useDispatch<\/code>aktualizujemy warto\u015b\u0107 meta postu. Ale aby pole tekstowe dzia\u0142a\u0142o poprawnie (a tak\u017ce pokazywa\u0142o aktualn\u0105 warto\u015b\u0107), musieliby\u015bmy r\u00f3wnie\u017c pobra\u0107 warto\u015b\u0107 meta postu.<\/p>\n<p>Je\u015bli potrzebujesz u\u017cy\u0107 wielu komponent\u00f3w wy\u017cszego rz\u0119du owini\u0119tych wok\u00f3\u0142 twojego komponentu, najprawdopodobniej u\u017cyjesz jeszcze innej funkcji Gutenberga; <code>[compose](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-compose\/)<\/code>. Jest to przydatna funkcja \u0142\u0105czenia wielu komponent\u00f3w wy\u017cszego rz\u0119du w jeden komponent wy\u017cszego rz\u0119du, wok\u00f3\u0142 kt\u00f3rego mo\u017cesz owin\u0105\u0107 sw\u00f3j komponent.<\/p>\n<p>Przyjrzyjmy si\u0119 pe\u0142niejszemu przyk\u0142adowi komponentu, kt\u00f3ry pobiera warto\u015b\u0107 meta posta w polu tekstowym i aktualizuje si\u0119, gdy jego warto\u015b\u0107 zostanie zmieniona. Zaczniemy od tego, jak musieliby\u015bmy si\u0119 do tego zabra\u0107 za pomoc\u0105 <code>withSelect<\/code>i <code>withDispatch<\/code>(a wi\u0119c tak\u017ce <code>compose<\/code>).<\/p>\n<h3>Korzystanie <code>withSelect<\/code>z, <code>withDispatch<\/code>i<code>compose<\/code><\/h3>\n<pre><code>const { __ } = wp.i18n;\nconst { compose } = wp.compose;\nconst { withSelect, withDispatch } = wp.data;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\n\u00a0\nconst AWP_Example_Plugin = ({ postMeta, setPostMeta }) =&gt; {\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'withSelect and withDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ postMeta.example_post_meta }\n                    onChange={ (value) =&gt; setPostMeta( { example_post_meta: value }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default compose( [\n    withSelect( (select) =&gt; {     \n        return {\n            postMeta: select( 'core\/editor' ).getEditedPostAttribute( 'meta' ),\n        };\n    } ),\n    withDispatch( (dispatch) =&gt; {\n        return {\n            setPostMeta( newMeta) {\n                dispatch( 'core\/editor' ).editPost( { meta: newMeta } );\n            }\n        };\n    }) ] )( AWP_Example_Plugin );<\/code><\/pre>\n<p>Na linii <code>#21-34<\/code>komponujemy <code>withSelect<\/code>i <code>withDispatch<\/code>owijamy je wok\u00f3\u0142 naszego komponentu. <code>postMeta<\/code>from <code>withSelect<\/code>i <code>setPostMeta<\/code>from <code>withDispatch<\/code>s\u0105 teraz dost\u0119pne w naszym komponencie jako rekwizyty. Destrukujemy je na linii <code>#7<\/code>i wykorzystujemy w <code>#13<\/code>i <code>#14<\/code>.<\/p>\n<p>Jak wida\u0107, niezb\u0119dny kod poza naszym komponentem jest d\u0142u\u017cszy ni\u017c sam komponent. Nie wiem jak wy, ale dla mnie to troch\u0119 chaotyczne. Deweloperzy mog\u0105 zacz\u0105\u0107 czyta\u0107 ten kod od g\u00f3ry, nie widz\u0105c dolnej cz\u0119\u015bci, i zacz\u0105\u0107 si\u0119 zastanawia\u0107, sk\u0105d <code>postMeta<\/code>i <code>setPostMeta<\/code>sk\u0105d \u2013 wydaj\u0105 si\u0119 by\u0107 magicznie dost\u0119pne. Dla mnie jest to bardzo nieintuicyjne.<\/p>\n<p>Przyjrzyjmy si\u0119, jak zamieniliby\u015bmy powy\u017cszy przyk\u0142ad na haki.<\/p>\n<h3>Korzystanie <code>useSelect<\/code>i<code>useDispatch<\/code><\/h3>\n<pre><code>const { __ } = wp.i18n;\nconst { useSelect, useDispatch } = wp.data;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\n\u00a0\nconst AWP_Example_Plugin = () =&gt; {\n    const { postMeta } = useSelect( (select) =&gt; {     \n        return {\n            postMeta: select( 'core\/editor' ).getEditedPostAttribute( 'meta' ),\n        };\n    } );\n    const { editPost } = useDispatch( 'core\/editor', [ postMeta.example_post_meta ] );\n\u00a0\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'useSelect and useDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ postMeta.example_post_meta }\n                    onChange={ (value) =&gt; editPost( { meta: { example_post_meta: value } }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>Jak pi\u0119kne i czytelne jest to?! Od razu widzimy w naszym komponencie, sk\u0105d <code>postMeta<\/code>jest pobierany i jak uzyskujemy dost\u0119p do <code>editPost<\/code>. Nasz komponent sta\u0142 si\u0119 r\u00f3wnie\u017c znacznie \u0142atwiejszy w ponownym u\u017cyciu.<\/p>\n<p>Zauwa\u017c, \u017ce w <code>useDispatch<\/code>linii <code>#12<\/code>dodajemy postmet\u0119, kt\u00f3r\u0105 aktualizujemy jako zale\u017cno\u015b\u0107 (<code>postMeta.example_post_meta<\/code>). Je\u015bli mia\u0142by\u015b aktualizowa\u0107 wiele zmiennych meta postu w tym komponencie, musia\u0142by\u015b doda\u0107 ka\u017cd\u0105 z nich jako zale\u017cno\u015b\u0107, aby upewni\u0107 si\u0119, \u017ce wysy\u0142anie zostanie uruchomione (w\u0142a\u015bciwie zapisuj\u0105c meta post), gdy warto\u015b\u0107 jednej z nich ulegnie zmianie.<\/p>\n<p>Mam nadziej\u0119, \u017ce by\u0142o to dla kogo\u015b pouczaj\u0105ce i pomocne. Wci\u0105\u017c nie jestem zaznajomiony z haczykami, ale widz\u0105c korzy\u015bci z ich u\u017cywania, nie cofam si\u0119!<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wprowadzenie do korzystania z hook\u00f3w React useSelect i useDispatch. Zobaczymy, jak to jest korzystne, dlaczego powinni\u015bmy to robi\u0107 i dok\u0142adnie w jaki spos\u00f3b.<\/p>\n","protected":false},"author":1,"featured_media":151604,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[940,940,1110,815,845,845,866,866,815],"tags":[1169],"class_list":["post-233951","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gutenberg-7","category-n-a","category-wtyczki","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233951","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=233951"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233951\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/151604"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=233951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=233951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=233951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}