vocadb icon indicating copy to clipboard operation
vocadb copied to clipboard

React conversion

Open ycanardeau opened this issue 4 years ago • 0 comments

Tasks

  • [x] #862
  • [x] #901
  • [x] #1133
  • [x] #902
  • [ ] #906
  • [x] #909
  • [ ] #1000
  • [ ] #1067
  • [ ] #853
  • [ ] #1169
  • [ ] #1170

Motivation

Currently we are facing several issues with frontend development.

It's impossible to find JavaScript errors in cshtml files at compile-time, rather than at run-time.

JavaScript code is scattered around ts and cshtml files, which makes code splitting and dynamic imports difficult. Now that we are using Webpack through Laravel Mix (#5 and #540, powered by ReMikus), we can easily make use of code splitting in React. See also #872.

The jQuery and jQuery UI packages cannot be upgraded easily, because there seem to be some breaking changes. This is why #675 and #679 cannot be merged.

It requires boilerplate code to translate user interfaces. In the current implementation, we need to

  1. create/edit a resx file
  2. update ResourcesApiController if needed
  3. create a ResourceRepository and pass it to a viewmodel
  4. create a ResourcesManager with the repository and current UI culture.
  5. load resources

, which is a lot of pain. By using i18next and react-i18next, we can make this process a lot easier.

We have two different libraries for the same thing, for example marked and MarkdownSharp (#38 and #904).

Why React?

There are several reasons why I chose React, but the main reasons are that

  1. React is developed and maintained by Facebook and a community of individual developers and companies.
  2. React is used by DeviantArt, Discord, Mastodon and MusicBrainz.
  3. TypeScript supports JSX.
  4. I like the React way of thinking (one-way data flow, function components, JSX and etc.).
  5. There is a way to integrate with other libraries.
  6. Using create-react-app is optional.
  7. We are still using customized Bootstrap 2 and this could be replaced with react-bootstrap.

I decided to use MobX, not Redux, for state management. This is because MobX API is surprisingly similar to Knockout's. The conversion shouldn't be that hard, although there are subtle differences in behavior between them (e.g. subscribe and reaction).

Of course this would be nearly impossible to do all at once, it has to be done gradually.

Examples

Before:

<div class="label label-info" data-bind="click: function() { $parent.advancedFilters.filters.remove($data); }">

Who is the $parent in this context?

After:

<div
    className="label label-info"
    onClick={(): void => advancedFilters.remove(filter)}
>

ycanardeau avatar Jul 03 '21 15:07 ycanardeau