{"id":21322,"date":"2023-05-08T05:00:00","date_gmt":"2023-05-08T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=21322"},"modified":"2024-07-22T15:00:29","modified_gmt":"2024-07-22T13:00:29","slug":"nowosci-w-react-18","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/nowosci-w-react-18\/","title":{"rendered":"Nowo\u015bci w React 18"},"content":{"rendered":"\n<p>W pa\u017adzierniku 2020 roku ukaza\u0142a si\u0119 wersja Reacta 17, kt\u00f3ra nie wprowadzi\u0142a zbyt wielu nowo\u015bci. Po oko\u0142o 1,5 roku od tej daty pojawi\u0142o si\u0119 wydanie Reacta 18. Znalaz\u0142o si\u0119 w nim wiele zmian, kt\u00f3re powinny przyku\u0107 uwag\u0119 niejednego front-end developera. W tym artykule przedstawi\u0119 czego mo\u017cemy si\u0119 spodziewa\u0107 w najnowszej wersji tej biblioteki.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Instalacja i aktualizacja Reacta do wersji 18<\/strong><\/h2>\n\n\n\n<p>Aby zainstalowa\u0107 Reacta 18, nale\u017cy w konsoli u\u017cy\u0107 nast\u0119puj\u0105cej komendy: \u201enpm install react@18 react-dom@18\u201d lub \u201enpm install react react-dom\u201d. Mo\u017cemy r\u00f3wnie\u017c skorzysta\u0107 z polecenia \u201enpx create-react-app nazwa_aplikacji\u201d, je\u015bli chcemy, \u017ceby zosta\u0142a tak\u017ce stworzona od razu podstawowa struktura projektu.<\/p>\n\n\n\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce je\u015bli chcemy zaktualizowa\u0107 do wersji React 18 ju\u017c istniej\u0105cy projekt, to starsz\u0105 funkcj\u0119 ReactDom.render nale\u017cy zast\u0105pi\u0107 nowsz\u0105 funkcj\u0105 ReactDom.createRoot. Nast\u0119puj\u0105cy fragment kodu:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport ReactDOM from &#039;react-dom&#039;;\nimport App from &#039;.\/App&#039;;\n\nReactDOM.render(&lt;App \/&gt;, document.getElementById(&#039;root&#039;));\n<\/pre><\/div>\n\n\n<p>trzeba zamieni\u0107 na poni\u017cszy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport ReactDOM from &quot;react-dom\/client&quot;;\nimport App from &quot;.\/App&quot;;\n\nconst root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));\nroot. Render(&lt;App \/&gt;);\n<\/pre><\/div>\n\n\n<p>Je\u015bli tego nie zrobimy, aplikacja nadal b\u0119dzie dzia\u0142a\u0107, ale nie b\u0119dziemy mieli mo\u017cliwo\u015bci skorzystania z nowych funkcjonalno\u015bci, kt\u00f3re pojawi\u0142y si\u0119 w aktualnej wersji i dzi\u0119ki kt\u00f3rym program jest w stanie osi\u0105gn\u0105\u0107 lepsz\u0105 wydajno\u015b\u0107.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Concurrent rendering mode<\/strong><\/h2>\n\n\n\n<p>Jedn\u0105 z najistotniejszych zmian, jakie zosta\u0142y wprowadzone, jest concurrent mode, czyli <strong>mo\u017cliwo\u015b\u0107 renderowania wsp\u00f3\u0142bie\u017cnego<\/strong>. Nie jest to funkcjonalno\u015b\u0107, z kt\u00f3rej mo\u017cna bezpo\u015brednio skorzysta\u0107. Jest ona zaimplementowana pod mask\u0105 Reacta i wykorzystuje takie techniki jak kolejki priorytet\u00f3w czy wielokrotne buforowanie. Jednak, jak sama dokumentacja wskazuje, znajomo\u015b\u0107 implementacji tej funkcjonalno\u015bci nie jest potrzebna dla dewelopera.<\/p>\n\n\n\n<p>Tryb renderowania wsp\u00f3\u0142bie\u017cnego, kt\u00f3ry zosta\u0142 wprowadzony, znacz\u0105co poprawia wydajno\u015b\u0107 renderowania aplikacji. Daje on mo\u017cliwo\u015b\u0107 ustalania priorytet\u00f3w, kolejkowania oraz przerywania render\u00f3w w programie. W dalszej cz\u0119\u015bci artyku\u0142u znajdziecie informacje, jak wykorzysta\u0107 ten tryb, u\u017cywaj\u0105c np. hooka useTransition przy pomocy, kt\u00f3rego mo\u017cna ustali\u0107, kt\u00f3re renderingi s\u0105 bardziej priorytetowe od innych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Transitions<\/strong><\/h2>\n\n\n\n<p>Nowym elementem, jaki pojawi\u0142 si\u0119 w React 18 s\u0105 \u201etransitions\u201d czyli przej\u015bcia. Daj\u0105 one mo\u017cliwo\u015b\u0107 ustalenia, <strong>kt\u00f3re aktualizacje interfejsu u\u017cytkownika s\u0105 pilne<\/strong>, a kt\u00f3re mniej. Jako przyk\u0142ady pilnych aktualizacji mo\u017cna wskaza\u0107 takie interakcje jak wpisywanie tekstu w pole tekstowe czy klikni\u0119cie przycisku. \u201eTransitions\u201d dostarczaj\u0105 hook o nazwie useTransition. Je\u015bli korzystamy z komponent\u00f3w opartych o klasy, mo\u017cemy skorzysta\u0107 z funkcji startTransition.<\/p>\n\n\n\n<p>Przyk\u0142adem, kiedy przej\u015bcia okazuj\u0105 si\u0119 przydatne, mo\u017ce by\u0107 input do filtrowania danych po nazwie wykorzystuj\u0105cy event onChange. Za\u0142\u00f3\u017cmy, \u017ce w evencie jest wykonywane filtrowanie, kt\u00f3re zajmuje nieco czasu. W takim przypadku, gdy u\u017cytkownik wpisuje tekst do inputa, to z op\u00f3\u017anieniem b\u0119dzie widzia\u0142 to, co do niego wpisa\u0142. Przy pomocy przej\u015b\u0107 mo\u017cemy sprawi\u0107, aby aktualizacja stanu w polu tekstowym by\u0142a bardziej priorytetowa ni\u017c wy\u015bwietlenie przefiltrowanych danych.<\/p>\n\n\n\n<p>Dla zobrazowania pos\u0142u\u017c\u0119 si\u0119 kodem aplikacji, kt\u00f3ry wykonuj\u0105c 10 tysi\u0119cy iteracji w p\u0119tli, ma za zadanie wylosowa\u0107 unikalne liczby z zakresu od 1 do x + 100 000, gdzie x to warto\u015b\u0107 wpisana do inputa. Nast\u0119pnie wszystkie wylosowane liczby maj\u0105 zosta\u0107 wy\u015bwietlone. Po uruchomieniu poni\u017cszego kodu mo\u017cna zauwa\u017cy\u0107, \u017ce wci\u015bni\u0119cie jakiejkolwiek liczby na klawiaturze (b\u0119d\u0105c w polu numerycznym) doprowadzi do jej pojawienia si\u0119 z pewnym op\u00f3\u017anieniem w tym inpucie.<\/p>\n\n\n\n<p>Aby bardziej wyra\u017anie zaobserwowa\u0107 to niepo\u017c\u0105dane zjawisko, mo\u017cna zmniejszy\u0107 wydajno\u015b\u0107 procesora w przegl\u0105darce przy u\u017cyciu narz\u0119dzi deweloperskich.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useState } from &quot;react&quot;;\n\nconst App = () =&gt; {\n  const &#x5B;inputValue, setInputValue] = useState(&quot;&quot;);\n  const &#x5B;numbers, setNumbers] = useState(&#x5B;]);\n\n  const drawNumbers = (event) =&gt; {\n    setInputValue(event.target.value);\n    if (event.target.value) {\n      const drawnNumbers = new Set();\n      const multipler = 100000 + parseInt(event.target.value);\n      for (let i = 0; i &lt; 10000; i++) {\n        const randomNumber = Math.floor(Math.random() * multipler + 1);\n        drawnNumbers.add(randomNumber);\n      }\n      setNumbers(&#x5B;...drawnNumbers]);\n    } else {\n      setNumbers(&#x5B;]);\n    }\n  };\n\n  return (\n    &lt;&gt;\n      &lt;input type=&quot;number&quot; onChange={drawNumbers} value={inputValue} \/&gt;\n      {numbers.map((number) =&gt; (\n        &lt;p key={number}&gt;{number}&lt;\/p&gt;\n      ))}\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n<\/pre><\/div>\n\n\n<p>Rozwi\u0105zaniem tego problemu jest wykorzystanie tzw. przej\u015b\u0107, co zosta\u0142o zaprezentowane w nast\u0119pnym fragmencie kodu. Zosta\u0142 w nim u\u017cyty hook useTransition, kt\u00f3ry dostarcza tablic\u0119 dwuelementow\u0105. W jej pierwszym elemencie znajduje si\u0119 flaga isPending, kt\u00f3ra informuje, czy komponent jest w trakcie wykonywania przej\u015bcia. Drugi element to funkcja startTransition, w kt\u00f3r\u0105 powinny zosta\u0107 opakowane niekrytyczne aktualizacje interfejsu. W przypadku poni\u017cszego kodu jest to aktualizacja stanu wylosowanych liczb.<\/p>\n\n\n\n<p>Dzi\u0119ki temu zmiana stanu w inpucie ma wy\u017cszy priorytet przy renderowaniu i tym samym op\u00f3\u017anienie po wci\u015bni\u0119ciu dowolnej liczby na klawiaturze zosta\u0142o znacz\u0105co zniwelowane. Aktualizacje, kt\u00f3re znajduj\u0105 si\u0119 w startTransition, s\u0105 traktowane jako mniej priorytetowe i zostaj\u0105 przerwane, gdy w programie pojawi\u0105 si\u0119 bardziej pilne zmiany takie jak np. klikni\u0119cie przycisku lub wpisywanie tekstu do pola tekstowego.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useState, useTransition } from &quot;react&quot;;\n\nconst App = () =&gt; {\n  const &#x5B;inputValue, setInputValue] = useState(&quot;&quot;);\n  const &#x5B;numbers, setNumbers] = useState(&#x5B;]);\n  const &#x5B;isPending, startTransition] = useTransition();\n\n  const drawNumbers = (event) =&gt; {\n    setInputValue(event.target.value);\n    startTransition(() =&gt; {\n      if (event.target.value) {\n        const drawnNumbers = new Set();\n        const multipler = 100000 + parseInt(event.target.value);\n        for (let i = 0; i &lt; 10000; i++) {\n          const randomNumber = Math.floor(Math.random() * multipler + 1);\n          drawnNumbers.add(randomNumber);\n        }\n        setNumbers(&#x5B;...drawnNumbers]);\n      } else {\n        setNumbers(&#x5B;]);\n      }\n    });\n  };\n\n  return (\n    &lt;&gt;\n      &lt;input type=&quot;number&quot; onChange={drawNumbers} value={inputValue} \/&gt;\n      {isPending ? (\n        &lt;p&gt;Loading&lt;\/p&gt;\n      ) : (\n        numbers.map((number) =&gt; &lt;p key={number}&gt;{number}&lt;\/p&gt;)\n      )}\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>useDeferredValue<\/strong><\/h2>\n\n\n\n<p>useDeferredValue to hook, kt\u00f3ry daje mo\u017cliwo\u015b\u0107 przesuni\u0119cia w czasie ma\u0142o istotnych aktualizacji interfejsu u\u017cytkownika. Innymi s\u0142owy ma za zadanie odroczy\u0107 wyrenderowanie stanu o ni\u017cszym priorytecie. Jako parametr przyjmuje warto\u015b\u0107, kt\u00f3ra ma zosta\u0107 odroczona oraz zwraca t\u0119 odroczon\u0105 warto\u015b\u0107. W por\u00f3wnaniu do hooka useTransition wykorzystuje si\u0119 go, gdy nie mamy pe\u0142nej kontroli nad aktualizacj\u0105 stanu np. gdy przekazujemy warto\u015b\u0107 stanow\u0105 przy u\u017cyciu props\u00f3w.<\/p>\n\n\n\n<p>Aby rozwi\u0105za\u0107 problem, kt\u00f3ry zosta\u0142 przedstawiony w poprzednim przyk\u0142adzie polegaj\u0105cy na <strong>op\u00f3\u017anionym wy\u015bwietleniu w polu numerycznym liczby<\/strong>, kt\u00f3ra zosta\u0142a wci\u015bni\u0119ta na klawiaturze, mo\u017cna r\u00f3wnie\u017c skorzysta\u0107 z hooka useDeferredValue, co zaprezentowa\u0142em poni\u017cej. Poprzedni kod zosta\u0142 nieco zmieniony przez dodanie komponentu NumbersList, w kt\u00f3rym wy\u015bwietlone zostaj\u0105 wylosowane liczby oraz w kt\u00f3rym zosta\u0142 wykorzystany omawiany hook.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useState } from &quot;react&quot;;\nimport NumbersList from &quot;.\/NumbersList&quot;;\n\nconst App = () =&gt; {\n  const &#x5B;inputValue, setInputValue] = useState(&quot;&quot;);\n  const &#x5B;numbers, setNumbers] = useState(&#x5B;]);\n\n  const drawNumbers = (event) =&gt; {\n    setInputValue(event.target.value);\n    if (event.target.value) {\n      const drawnNumbers = new Set();\n      const multipler = 100000 + parseInt(event.target.value);\n      for (let i = 0; i &lt; 10000; i++) {\n        const randomNumber = Math.floor(Math.random() * multipler + 1);\n        drawnNumbers.add(randomNumber);\n      }\n      setNumbers(&#x5B;...drawnNumbers]);\n    } else {\n      setNumbers(&#x5B;]);\n    }\n  };\n\n  return (\n    &lt;&gt;\n      &lt;input type=&quot;number&quot; onChange={drawNumbers} value={inputValue} \/&gt;\n      &lt;NumbersList numbers={numbers}&gt;&lt;\/NumbersList&gt;\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n\n\nimport React, { useDeferredValue } from &quot;react&quot;;\n\nconst NumbersList = ({ numbers }) =&gt; {\n  const deferredNumbers = useDeferredValue(numbers);\n  return (\n    &lt;&gt;\n      {deferredNumbers.map((number) =&gt; (\n        &lt;p key={number}&gt;{number}&lt;\/p&gt;\n      ))}\n    &lt;\/&gt;\n  );\n};\n\nexport default NumbersList;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>useId<\/strong><\/h2>\n\n\n\n<p>Nowy hook useId zosta\u0142 stworzony w celu generowania unikatowych id zar\u00f3wno po stronie klienta jak i po stronie serwera. Tego hooka nie powinno si\u0119 wykorzystywa\u0107 do generowania kluczy w li\u015bcie. Mo\u017cna go u\u017cy\u0107 w celu po\u0142\u0105czenia element\u00f3w html takich jak input oraz label co zosta\u0142o zilustrowane w przyk\u0142adzie poni\u017cej.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useId } from &#039;react&#039;;\n\nconst App = () =&gt; {\n  const id = useId();\n\n  return (\n    &lt;&gt;\n      &lt;label htmlFor={&quot;fullName-&quot; + id}&gt;Full Name: &lt;\/label&gt;\n      &lt;div&gt;\n        &lt;input id={&quot;fullName-&quot; + id} type=&quot;test&quot; \/&gt;\n      &lt;\/div&gt;\n      &lt;label htmlFor={&quot;emailAddress-&quot; + id}&gt;Email: &lt;\/label&gt;\n      &lt;div&gt;\n        &lt;input id={&quot;emailAddress-&quot; + id} type=&quot;email&quot; \/&gt;\n      &lt;\/div&gt;\n    &lt;\/&gt;\n  );\n}\n\nexport default App;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>useSyncExternalStore<\/strong><\/h2>\n\n\n\n<p>Jest to hook przeznaczony dla autor\u00f3w bibliotek zwi\u0105zanych z zarz\u0105dzaniem stanem w React. Zosta\u0142 wprowadzony po to, aby zapewni\u0107 pomoc przy implementowaniu zmian stanu po tym jak wprowadzono tryb wsp\u00f3\u0142bie\u017cny.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>useInsertionEffect<\/strong><\/h2>\n\n\n\n<p>Ten hook wykorzystywany jest przez tw\u00f3rc\u00f3w bibliotek CSS-in-JS. Jest on pewn\u0105 wersj\u0105 hooka useEffect, ale jest on wywo\u0142ywany synchronicznie przed wszystkimi mutacjami DOM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Strict Mode<\/strong><\/h2>\n\n\n\n<p>W bibliotece React, Strict Mode to narz\u0119dzie, kt\u00f3re informuje o potencjalnych problemach w\u00a0aplikacji. Mo\u017cemy je doda\u0107 dla ca\u0142ej lub cz\u0119\u015bci aplikacji. Aby to zrobi\u0107 w wybranych komponentach, nale\u017cy je owin\u0105\u0107 w komponent &lt;React.StrictMode>. W najnowszej wersji Reacta zosta\u0142o dodane nowe zachowanie trybu Strict Mode, a mianowicie \u2013 tryb \u015bcis\u0142y mo\u017ce teraz obs\u0142ugiwa\u0107 montowanie i demonta\u017c komponent\u00f3w, a w przysz\u0142o\u015bci ma zachowywa\u0107 i przywraca\u0107 ich stan przy kolejnych montowaniach.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Automatic batching<\/strong><\/h2>\n\n\n\n<p>Do tej pory w React wyst\u0119powa\u0142 tzw. state batching, ale by\u0142 bardziej ograniczony ni\u017c automatic batching. Je\u015bli wyst\u0105pi\u0142y dwie aktualizacje stanu lub wi\u0119cej, to mia\u0142 on za zadanie grupowanie aktualizacji stan\u00f3w tak, aby nast\u0105pi\u0142 tylko jeden ponowny rendering komponentu. Jednak mia\u0142o to tylko miejsce w \u015brodku tzw. synthetic events (onClick, onChange itd.), tak jak pokaza\u0142em ni\u017cej.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useState } from &quot;react&quot;;\n\nconst App = () =&gt; {\n  const &#x5B;counter, setCounter] = useState(0);\n  const &#x5B;toogle, setToogle] = useState(false);\n\n  const incrementCounter = () =&gt; {\n    setCounter(counter + 1);\n    setToogle(!toogle);\n  };\n\n  return (\n    &lt;&gt;\n      &lt;button\n        onClick={incrementCounter}\n        style={{ color: toogle ? &quot;blue&quot; : &quot;green&quot; }}\n      &gt;\n        Increment Counter\n      &lt;\/button&gt;\n      {&lt;p&gt;counter : {counter}&lt;\/p&gt;}\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n<\/pre><\/div>\n\n\n<p>Po uruchomieniu powy\u017cszego kodu, zar\u00f3wno w starszej jak i najnowszej wersji Reacta, komponent zostanie tylko raz przerenderowany po klikni\u0119ciu przycisku.<\/p>\n\n\n\n<p>Natomiast je\u015bli b\u0119d\u0105 aktualizowane dwa stany lub wi\u0119cej w promise, funkcji setTimeout lub natywnym event handlerze, to w przypadku, gdy aplikacja korzysta ze starszej wersji Reacta, komponent zostanie kilka razy przerysowany. Dla odmiany automatic batching grupuje aktualizacje stan\u00f3w nawet wtedy, gdy znajduj\u0105 si\u0119 one we wcze\u015bniej wymienionych miejscach. W kodzie, kt\u00f3ry doda\u0142em pod spodem, znajduje si\u0119 promise w funkcji getData, w kt\u00f3rym uaktualniane s\u0105 dwa stany.<\/p>\n\n\n\n<p>Mimo to w najnowszym wydaniu Reacta, wykonuj\u0105c funkcje getData, komponent wyrenderuje si\u0119 ponownie tylko raz. \u00a0<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { useState } from &quot;react&quot;;\n\nconst App = () =&gt; {\n  const &#x5B;products, setProducts] = useState(&#x5B;]);\n  const &#x5B;, setIsDownloaded] = useState(false);\n\n  const getData = async () =&gt; {\n    fetch(&quot;https:\/\/dummyjson.com\/products&quot;, {\n      method: &quot;GET&quot;\n    }).then((response) =&gt;\n      response.json().then((response) =&gt; {\n        setProducts(response.products);\n        setIsDownloaded(true);\n      })\n    );\n  };\n\n  return (\n    &lt;&gt;\n      &lt;button onClick={getData}&gt;Get Data&lt;\/button&gt;\n      {products.map((product) =&gt; (\n        &lt;p key={product.id}&gt;{product.title}&lt;\/p&gt;\n      ))}\n    &lt;\/&gt;\n  );\n};\n\nexport default App;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Suspense<\/strong><\/h2>\n\n\n\n<p>W najnowszym wydaniu Reacta dodano mo\u017cliwo\u015b\u0107 wykorzystania komponentu Suspense po stronie serwera m.in. z takimi frameworkami jak Next.js czy Remix.<\/p>\n\n\n\n<p>Wcze\u015bniej komponent ten by\u0142o mo\u017cna u\u017cy\u0107 tylko po stronie klienta w po\u0142\u0105czeniu z komponentami leniwymi. Wy\u015bwietla\u0142 w\u00f3wczas komponent zast\u0119pczy, kt\u00f3ry przekazuje si\u0119 we w\u0142a\u015bciwo\u015bci fallback i jest prezentowany, dop\u00f3ki komponent lub komponenty znajduj\u0105ce si\u0119 w \u015brodku komponentu Suspense nie za\u0142adowa\u0142y si\u0119 w pe\u0142ni. Zaprezentowa\u0142em to poni\u017cej.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport React, { lazy, Suspense } from &quot;react&quot;;\n\nconst loadingTime = 2000;\nconst delayRendering = (component) =&gt;\n  new Promise((resolve) =&gt; setTimeout(() =&gt; resolve(component), loadingTime));\n\nconst HomePage = lazy(() =&gt; delayRendering(import(&quot;.\/HomePage&quot;)));\nconst Loading = () =&gt; &lt;div&gt;Loading...&lt;\/div&gt;;\n\nconst App = () =&gt; {\n  return (\n    &lt;Suspense fallback={&lt;Loading \/&gt;}&gt;\n      &lt;HomePage&gt;&lt;\/HomePage&gt;\n    &lt;\/Suspense&gt;\n  );\n};\n\nexport default App;\n\n\n\nimport React from &quot;react&quot;;\n\nconst HomePage = () =&gt; {\n  return &lt;p&gt;Home Page&lt;\/p&gt;;\n};\n\nexport default HomePage;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>W wersji React 18 wprowadzone du\u017ce zmiany, kt\u00f3rych g\u0142\u00f3wnym zadaniem jest poprawa wydajno\u015bci renderowanych aplikacji. Wi\u0119kszo\u015b\u0107 wprowadzonych nowo\u015bci bazuje na trybie renderowania wsp\u00f3\u0142bie\u017cnego, na co czekali\u015bmy od dawna. Dzi\u0119ki pojawieniu si\u0119 tych mo\u017cliwo\u015bci, React ma szans\u0119 zyska\u0107 jeszcze wi\u0119ksz\u0105 popularno\u015b\u0107 ni\u017c ma obecnie.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0179r\u00f3d\u0142a<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li><a href=\"https:\/\/reactjs.org\/blog\/2022\/03\/29\/react-v18.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >React Dev Blog<\/a><\/li><li><a href=\"https:\/\/reactjs.org\/docs\/hooks-reference.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Legacy ReactJS<\/a><\/li><li><a href=\"https:\/\/vived.io\/pl\/frontend-thursday-vol-81-react-18\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Vived Blog<\/a><\/li><\/ol>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u015bli interesuje Ci\u0119 tematyka Reacta, zajrzyj r\u00f3wnie\u017c <a href=\"https:\/\/sii.pl\/blog\/wyszukiwarka\/react\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">do innych artyku\u0142\u00f3w naszych ekspert\u00f3w<\/a>.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;21322&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;12&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.9&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.9\\\/5 ( votes: 12)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Nowo\u015bci w React 18&quot;,&quot;width&quot;:&quot;136.6&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 136.6px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.9\/5 ( votes: 12)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>W pa\u017adzierniku 2020 roku ukaza\u0142a si\u0119 wersja Reacta 17, kt\u00f3ra nie wprowadzi\u0142a zbyt wielu nowo\u015bci. Po oko\u0142o 1,5 roku od &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/nowosci-w-react-18\/\">Continued<\/a><\/p>\n","protected":false},"author":506,"featured_media":21326,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":6,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2427,1546,113,202,991],"class_list":["post-21322","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-digital","tag-przeglad-narzedzi","tag-frontend","tag-javascript","tag-react"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/04\/Nowosci-w-React-18.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21322"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/506"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=21322"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21322\/revisions"}],"predecessor-version":[{"id":21331,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21322\/revisions\/21331"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/21326"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=21322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=21322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=21322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}