Skip to content

React from angularjs best practices

Adam Pelle edited this page Feb 24, 2020 · 4 revisions

Best Practices

We are using react2angular lib which can expose a react component to an angular counterpart. like <StepItem step={...} /> -> <r-step-item step="step"> so we can use them in angular templates like any other directives (note it's gonna be angular component not a directive!). Though it seems very neat and easy, we need to be aware of couple practices.

Exposing typescript services to angular

With webpack we can simply export/import components or functions like this:

// something.ts
class Something { ... }

// some_old_file.js.erb
import Something from './something';
angular.factory("blabla", function() { return new Something(); });

Bottom -> up approach

In order to keep things simple, we should start convert items from "leaves" to roots in angular templates. That means start elements from bottom (without children) and move to the top. During the way you can compose already existing elements e.g

step-list (angular)
  Step (react)
  | -> StepVersion (react)
  | -> StepDescription (react)

Use safe-digest everywhere

When communicating from react context to angular we need to call $scope.$digest() in order to trigger the digest cycle. However if we want to share functions between react and angular that's gonna be a problem, since $digest is causing error inside an already started cycle (in angular context). For that's reason you could use safeDigest($scope) from react-compat service. That only triggers digest outside of the cycle thus make it safe from both contexts.

Beware of constant references due to property bindings

In angular it's possible to bind to certain properties while keeping the reference intact <span ng-bind="{{ something.foo }}">. It's possible in this case something as a reference does not change only the foo. So when we pass it down to a bound react component <r-item something="something"/> the component won't re-render itself since it does not detect changes (in react components only re-renders itself when incoming prop changes). It's better to pass down individual properties <r-item foo="something.foo" /> so the prop changes for sure. However sometimes it can also work it depends entirely on angular implementation.

String management

As a leftover task from react transition we kept the strings in ruby file strings.rb. That means we can only use strings in .js.erb or .slim files at the moment. Until we figure out long term string management we must pass down strings to react components as props! Let's never ever use .erb file extension on a react component, in the long term we are migrating away from ruby string management. example:

// foo.slim
<r-step-item strings="{ 'string1': "#{ data[:something][:string] }" }" />

// stepitem.tsx
const StepItem = ({ strings: { string1 } }) => { ... };

Differentiate angular react wrappers

In order to easily distinguish react wrappers and simple angular components we should use some sort of convention. We started to apply a prefix r- to these components. Upon registration we need to use PascalCase but in html it's converted to snake-case by react2angular (convention over configuration approach).