-
Notifications
You must be signed in to change notification settings - Fork 21
React from angularjs 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.
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(); });
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)
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.
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.
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 } }) => { ... };
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).