Skip to content

React v18 ReactDOMClient #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 36 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
},
"homepage": "https://github.com/lumihq/purescript-react-basic-dom#readme",
"dependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1"
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"bower": "^1.8.12",
Expand Down
32 changes: 27 additions & 5 deletions src/React/Basic/DOM.purs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ module React.Basic.DOM
) where

import Prelude

import Effect (Effect)
import Prim.TypeError (class Warn, Text)
import React.Basic (JSX)
import React.Basic.DOM.Generated (Props_a, Props_abbr, Props_address, Props_area, Props_article, Props_aside, Props_audio, Props_b, Props_base, Props_bdi, Props_bdo, Props_blockquote, Props_body, Props_br, Props_button, Props_canvas, Props_caption, Props_cite, Props_code, Props_col, Props_colgroup, Props_data, Props_datalist, Props_dd, Props_del, Props_details, Props_dfn, Props_dialog, Props_div, Props_dl, Props_dt, Props_em, Props_embed, Props_fieldset, Props_figcaption, Props_figure, Props_footer, Props_form, Props_h1, Props_h2, Props_h3, Props_h4, Props_h5, Props_h6, Props_head, Props_header, Props_hgroup, Props_hr, Props_html, Props_i, Props_iframe, Props_img, Props_input, Props_ins, Props_kbd, Props_keygen, Props_label, Props_legend, Props_li, Props_link, Props_main, Props_map, Props_mark, Props_math, Props_menu, Props_menuitem, Props_meta, Props_meter, Props_nav, Props_noscript, Props_object, Props_ol, Props_optgroup, Props_option, Props_output, Props_p, Props_param, Props_picture, Props_pre, Props_progress, Props_q, Props_rb, Props_rp, Props_rt, Props_rtc, Props_ruby, Props_s, Props_samp, Props_script, Props_section, Props_select, Props_slot, Props_small, Props_source, Props_span, Props_strong, Props_style, Props_sub, Props_summary, Props_sup, Props_table, Props_tbody, Props_td, Props_template, Props_textarea, Props_tfoot, Props_th, Props_thead, Props_time, Props_title, Props_tr, Props_track, Props_u, Props_ul, Props_var, Props_video, Props_wbr, a, a', a_, abbr, abbr', abbr_, address, address', address_, area, area', article, article', article_, aside, aside', aside_, audio, audio', audio_, b, b', b_, base, base', bdi, bdi', bdi_, bdo, bdo', bdo_, blockquote, blockquote', blockquote_, body, body', body_, br, br', button, button', button_, canvas, canvas', canvas_, caption, caption', caption_, cite, cite', cite_, code, code', code_, col, col', colgroup, colgroup', colgroup_, data', data'', data_, datalist, datalist', datalist_, dd, dd', dd_, del, del', del_, details, details', details_, dfn, dfn', dfn_, dialog, dialog', dialog_, div, div', div_, dl, dl', dl_, dt, dt', dt_, em, em', em_, embed, embed', fieldset, fieldset', fieldset_, figcaption, figcaption', figcaption_, figure, figure', figure_, footer, footer', footer_, form, form', form_, h1, h1', h1_, h2, h2', h2_, h3, h3', h3_, h4, h4', h4_, h5, h5', h5_, h6, h6', h6_, head, head', head_, header, header', header_, hgroup, hgroup', hgroup_, hr, hr', html, html', html_, i, i', i_, iframe, iframe', iframe_, img, img', input, input', ins, ins', ins_, kbd, kbd', kbd_, keygen, keygen', keygen_, label, label', label_, legend, legend', legend_, li, li', li_, link, link', main, main', main_, map, map', map_, mark, mark', mark_, math, math', math_, menu, menu', menu_, menuitem, menuitem', menuitem_, meta, meta', meter, meter', meter_, nav, nav', nav_, noscript, noscript', noscript_, object, object', object_, ol, ol', ol_, optgroup, optgroup', optgroup_, option, option', option_, output, output', output_, p, p', p_, param, param', picture, picture', picture_, pre, pre', pre_, progress, progress', progress_, q, q', q_, rb, rb', rb_, rp, rp', rp_, rt, rt', rt_, rtc, rtc', rtc_, ruby, ruby', ruby_, s, s', s_, samp, samp', samp_, script, script', script_, section, section', section_, select, select', select_, slot, slot', slot_, small, small', small_, source, source', span, span', span_, strong, strong', strong_, style, style', style_, sub, sub', sub_, summary, summary', summary_, sup, sup', sup_, table, table', table_, tbody, tbody', tbody_, td, td', td_, template, template', template_, textarea, textarea', textarea_, tfoot, tfoot', tfoot_, th, th', th_, thead, thead', thead_, time, time', time_, title, title', title_, tr, tr', tr_, track, track', u, u', u_, ul, ul', ul_, var, var', var_, video, video', video_, wbr, wbr') as Generated
import React.Basic.DOM.Internal (CSS, css, mergeStyles, unsafeCreateDOMComponent) as Internal
Expand All @@ -28,15 +30,25 @@ import Web.DOM (Element)
-- | a DOM element.
-- |
-- | __*Note:* Relies on `ReactDOM.render`__
render :: JSX -> Element -> Effect Unit
render
:: Warn (Text "`render` has been replaced with `createRoot` in React 18")
=> JSX
-> Element
-> Effect Unit
render jsx node = render' jsx node (pure unit)

-- | Render or update/re-render a component tree into
-- | a DOM element. The given Effect is run once the
-- | DOM update is complete.
-- |
-- | __*Note:* Relies on `ReactDOM.render`__
render' :: JSX -> Element -> Effect Unit -> Effect Unit
-- | __*Note:* `render` has been replaced with `createRoot` in React 18
render'
:: Warn (Text "`render` has been replaced with `createRoot` in React 18")
=> JSX
-> Element
-> Effect Unit
-> Effect Unit
render' = renderThen

foreign import renderThen :: JSX -> Element -> Effect Unit -> Effect Unit
Expand All @@ -48,7 +60,11 @@ foreign import renderThen :: JSX -> Element -> Effect Unit -> Effect Unit
-- | __*Note:* Relies on `ReactDOM.hydrate`, generally only
-- | used with `ReactDOMServer.renderToNodeStream` or
-- | `ReactDOMServer.renderToString`__
hydrate :: JSX -> Element -> Effect Unit
hydrate
:: Warn (Text "`hydrate` has been replaced with `hydrateRoot` in React 18")
=> JSX
-> Element
-> Effect Unit
hydrate jsx node = hydrate' jsx node (pure unit)

-- | Render or update/re-render a component tree into
Expand All @@ -59,7 +75,12 @@ hydrate jsx node = hydrate' jsx node (pure unit)
-- | __*Note:* Relies on `ReactDOM.hydrate`, generally only
-- | used with `ReactDOMServer.renderToNodeStream` or
-- | `ReactDOMServer.renderToString`__
hydrate' :: JSX -> Element -> Effect Unit -> Effect Unit
hydrate'
:: Warn (Text "`hydrate` has been replaced with `hydrateRoot` in React 18")
=> JSX
-> Element
-> Effect Unit
-> Effect Unit
hydrate' = hydrateThen

foreign import hydrateThen :: JSX -> Element -> Effect Unit -> Effect Unit
Expand All @@ -69,6 +90,7 @@ foreign import hydrateThen :: JSX -> Element -> Effect Unit -> Effect Unit
-- | if an app existed and was unmounted successfully.
-- |
-- | __*Note:* Relies on `ReactDOM.unmountComponentAtNode`__
-- | __*Note:* `unmount` has been replaced with `Client.unmountRoot` in React 18
foreign import unmount :: Element -> Effect Boolean

-- | Divert a render tree into a separate DOM node. The node's
Expand All @@ -78,4 +100,4 @@ foreign import createPortal :: JSX -> Element -> JSX

-- | Create a text node.
text :: String -> JSX
text = unsafeCoerce
text = unsafeCoerce
11 changes: 11 additions & 0 deletions src/React/Basic/DOM/Client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ReactDOMClient from "react-dom/client";

export const createRoot = (container) => () =>
ReactDOMClient.createRoot(container);

export const hydrateRoot = (container) => (initialChildren) => () =>
ReactDOMClient.hydrateRoot(container, initialChildren);

export const renderRoot = (root) => (children) => () => root.render(children);

export const unmountRoot = (root) => () => root.unmount(root);
23 changes: 23 additions & 0 deletions src/React/Basic/DOM/Client.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module React.Basic.DOM.Client where

import Prelude
import React.Basic (JSX)
import Web.DOM (Element)
import Effect (Effect)

foreign import data ReactRoot :: Type

-- | Create a React root for the supplied container and return the root.
-- | The root can be used to render a React element into the DOM with `render.`
-- | Replaces `ReactDOM.render` when the `.render` method is called and enables Concurrent Mode.
foreign import createRoot :: Element -> Effect ReactRoot

-- | Same as `createRoot`, but is used to hydrate a container whose HTML contents were rendered by ReactDOMServer.
-- | React will attempt to attach event listeners to the existing markup.
foreign import hydrateRoot :: Element -> JSX -> Effect ReactRoot

-- | Render children in `ReactRoot`
foreign import renderRoot :: ReactRoot -> JSX -> Effect Unit

-- | Unmount the react root
foreign import unmountRoot :: ReactRoot -> Effect Unit
16 changes: 0 additions & 16 deletions src/React/Basic/DOM/Concurrent.js

This file was deleted.

16 changes: 0 additions & 16 deletions src/React/Basic/DOM/Concurrent.purs

This file was deleted.

4 changes: 1 addition & 3 deletions src/React/Basic/DOM/Server.js
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import ReactDOMServer from "react-dom/server.js";
export var renderToString = ReactDOMServer.renderToString;
export var renderToStaticMarkup = ReactDOMServer.renderToStaticMarkup;
export { renderToString, renderToStaticMarkup } from "react-dom/server";