Skip to the content.

A brief guide to the React migration

If you want get familiar with React, start with the official site. It has a nice tutorial and guide.

What do we want to achieve?

We want to have separate codebases for server and client. The client will be written in React.

We’ll replace the current AngularJS components one by one. Eventually, we’ll drop the AngularJS and create a React project.

Rationale

How to wire up React components to AngularJS?

Create a react component with a path modules/**/client/components/SomeName.component.js. It will get imported to Angular automatically. Then you can use this component within Angular like <some-name></some-name>. See an example component.

Please note: When you create a React component which is not imported to Angular (i.e. when it’s used in other React components only), skip the component in the filename - name it just SomeName.js.

Issues and solutions

Routing

We’re using UI-Router for AngularJS.

The different paths (i.e. /volunteering) are configured in /modules/**/client/config/**.client.routes.js. Look at the example and search for volunteering to see how a React component can be added to the router.

Where we used ui-sref in Angular views, we’ll use href in React components. This solution reloads the app and therefore is far from ideal.

Getting Data

API calls from React

If you need some new data from API, request them directly for React.

Put your methods with API calls to a separate file (i.e. modules/**/client/components/*.api.js (this is going to change)). Then import and call these methods in your React component as needed. We’re using axios library to make API requests.

import axios from 'axios';

export async function searchUsers(query) {
  return await axios.get(`/api/users?search=${query}`);
}

Passing data from Angular to React

If you need to provide data from Angular to a React component, you can pass them in html attributes. Then they’ll be available in the component as props.

In AngularJS view it will look like this:

<profile-view-basics profile="profileCtrl.profile"></profile-view-basics>

where profile-view-basics is a React component imported into AngularJS. We assume that profileCtrl is a variable available in the AngularJS view. (Look for profile-view-basics in an example.)

In React, we use the profile in props:

export default function ProfileViewBasics({ profile }) {
  return (
    <div>
      Username: 
    </div>
  );
}

// or equivalently, i.e. if you want to use a state

export default class ProfileViewBasics {

  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div>
        Username: 
      </div>
    );
  }
}

Internationalization (i18n)

Read a manual.

Testing

Testing is done with jest and React Testing Library.

React tests are ones that match the path modules/*/tests/client/components/*.test.js.

e.g. modules/core/tests/client/components/LanguageSwitch.test.js

We loosely follow the philosophy from Kent C. Dodds, summed up as:

testing using user facing features instead of implementation details

See these two articles by him for more explanation:

Time scale

We’ll have a separate React app by the end of 2018 or beginning of 2019.