How to migrate to reason-react 0.7 with full jsx3

Migrate your code to JSX3 using a script

Instead of using reason-react official upgrade path, that allow you to use jsx2 & jsx3 at the same time, which is nice but require an effort from you to make components written in one version to work with the other & vice-versa, we will follow an alternative upgrade path based on a reason react compat hook coupled with our compatibility layer bs-react-native-jsx3-compat

So first,

Install reason-react-native@^0.60.0 via yarn or npm,

Replace bs-react-native with bs-react-native-jsx3-compat (^0.11.1) in your package.json,

be sure that you use bs-platform@^7.0.0

⚠️ be sure to use "reason-react": "^0.9.0",

use react@^16.8.0,

add reason-react-compat@^0.4.0,

(if needed, upgrade some deps (eg: reason-apollo@^0.16.0)),

Workaround for git usage

If you use released packages, you can skip these steps.

yarn add https://github.com/reason-react-native/reason-react-native.git

run a dirty command to get proper setup when using bs-react-native-jsx3-compat: add as a prepare script

"prepare": "ln -sFf ../node_modules/reason-react-native-monorepo/reason-react-native/ ./node_modules",

run yarn prepare (this will be run each time you use yarn & will ensure that the trick is always around until you actually use released versions of this work)

Now you can try to compile your code but it's unecessarry. You might have tons of error because bs-react-native is full of jsx2 & we just migrated codebase to jsx3.

So please:

Ensure your project is full jsx3 (bsconfig.json: "reason": {"react-jsx": 3},)

Replace bs-react-native by bs-react-native-jsx3-compat in your bsconfig.json (or reason-react-native-monorepo/bs-react-native-jsx3-compat for git users, check the git monorepo trick if necessary)

🎉 Compilation time!

You should still have some errors, but probably not that much.

Time to fix remaining errors before everything works™

We did our best here to avoid you having to update/fix your code but there might still be some minor stuff to adjust

check children errors and remove let children = React.Children.toArray(children); that might have beed added without being necessary

you can safely remove spread ... for children

you might need to tweak place where children are optional with {children->Belt.Option.getWithDefault(React.null)}

Notes about ReasonReact.wrapJsForReason & ReasonReact.wrapReasonForJs

With reason-react 0.7 & new api, JavaScript code produced is just normal React code. So this things are not necessary anymore but are not handled by the script we used.

So you might need to remove those things & replace them with vanilla React code

Remove ReasonReact.wrapJsForReason (example)

Remove ReasonReact.wrapReasonForJs (example, another example )

Compilation time

When you don't have any errors, just compile & enjoy jsx3. You can even add reason-react-native to your bsconfig.json bs-dependencies & use it right away with awesome hooks !

Here are some commits that might help you

🙏 Please do not hesitate to share your experience with the migration. If the source is open, post your commit here, it could help someone without you even knowing 🤷‍

Need help to migrate ?

If you struggle with it & have questions, reach us on our discord server

🎉 If you are reading this, you can assume you are done & ready to work on other things, like feature & bugfix for your product.

But I have more time! I WANT MORE

You can do some easy stuff to cleanup your codebase now that everything is working and that you are ready to use reason-react 0.7:

Easy replacement

ReasonReact.string => React.string

ReasonReact.array => React.array

ReasonReact.null => React.null

ReasonReact.reactElement => React.element

...

More tricky ones

You can probably remove lot of unecessary wrapping for stateless component that don't use the lifecycle

ReactCompat.useRecordApi({ ...component, render: _self => {

Can be replaced with

({{

And

ReactCompat.useRecordApi({ ...component, render: _self =>

Can be replaced with

({

At this point, the 2 replacements above have generated syntax error, so you should try to replace

, });

with

});

You should also be able to drop some let component = ReasonReact.statelessComponent... too, since some won't be used anymore thanks to the last removal step we did.

Now rely on refmt to get a cleaner code and you are good to go!

Do not hesitate to share more tips & tricks to ease the migration!