从AngularJS到React&Redux —如何迁移您的Web应用

温浩大
2023-12-01

by Panagiotis Vrs

通过Panagiotis Vrs

从AngularJS到React&Redux —如何迁移您的Web应用 (From AngularJS to React & Redux — how to migrate your web app)

Some days ago I wanted to start implementing something I had in mind for the past 4 months: Migrating an AngularJS project to React with Redux state management.

几天前,我想开始实施过去四个月中想到的一些事情:将AngularJS项目迁移到具有Redux状态管理的React。

I did some research around the topic. And although there were some articles around Angular-to-React migration, I got lost. Also I couldn't find how you can have Redux over the project only for React.

我围绕这个话题做了一些研究。 而且,尽管有一些关于Angular到React迁移的文章,但我迷路了。 我也找不到如何仅针对React在项目上使用Redux。

There are hundreds of projects out there that will have to decide in the next years to move to another framework as AngularJS and its libraries will have less and less support from the community.

AngularJS及其库在社区中的支持将越来越少,因此有数百个项目在接下来的几年中必须决定迁移到另一个框架。

I though that this can be easier so that’s why i did it and kept some notes so I can share my findings.

我虽然这样会更容易,所以这就是为什么我这样做并保留了一些注释,以便我可以分享我的发现。

Starting with AngularJS migration to React is not an easy task. And what happens if you want to start using Redux for state management as well? Well this doesn’t have to be a nightmare!

从AngularJS迁移到React并不是一件容易的事。 如果您也想开始使用Redux进行状态管理,会发生什么? 好吧,这不一定是一场噩梦!

My project had already been switched to ES6 with Webpack, so that was one thing that helped a lot. So I suggest before making such a migration, to start using Webpack and module dependencies ASAP.

我的项目已经通过Webpack切换到ES6,这是一件很有帮助的事情。 因此,我建议在进行此类迁移之前,尽快开始使用Webpack和模块依赖项。

我的需求 (My needs)

I wanted to start moving that project from AngularJS to React so I could start using all the new features modern web has to offer regarding speed, splitting the code to smaller components and of course testing.

我想开始将该项目从AngularJS迁移到React,这样我就可以开始使用现代Web必须提供的有关速度的所有新功能,将代码拆分为较小的组件,当然还要进行测试。

I’m not going to lie — I wasn’t testing enough or really at all in this project. Two months before this migration, I started implementing some testing principles around the project so I could keep in track in some tasks. The bottom line — it was amazingly difficult to set up testing and coverage, and in the end it it took some time to run the tasks.

我不会说谎-在这个项目中我没有进行足够的测试或根本没有进行测试。 在迁移之前两个月,我开始在项目周围实施一些测试原则,以便可以跟踪一些任务。 底线-设置测试和覆盖范围非常困难,最终,运行任务花费了一些时间。

开始塑造它 (Start shaping it up)

The first thing that I did was to install all the necessary dependencies like react, react-dom, and react-redux. You can see also the versions I am using below.

我要做的第一件事是安装所有必需的依赖项,例如react,react-dom和react-redux。 您还可以在下面查看我使用的版本。

The coolest plugin of all was react2angular, which I used to translate all the React components into Angular components.

最酷的插件是react2angular,我用来将所有React组件转换为Angular组件。

Then for development we need to install babel dependencies to have all the cool ES6 features. Keep in mind that I already had Babel, and I was only pasting this in to see versions and to keep aligned.

然后,为了进行开发,我们需要安装babel依赖项以具有所有出色的ES6功能。 请记住,我已经有了Babel,并且只粘贴了它以查看版本并保持一致。

All done? Nice!

全做完了? 真好!

项目结构 (Project Structure)

This is what I wanted to do having this structure for the whole project. I saw it on a complete MERN project on Github because I used it on a small project to see how it will turn out its very simple and efficient. Splitting for each page (container component) and each page to have their components. You can also have a folder outside name components as well to keep all the global components there. Refer here if the code examples makes no sense ;)

这就是我想要在整个项目中使用这种结构的目的。 我在Github上的一个完整的MERN项目中看到了它,因为我在一个小项目上使用了它,以了解它如何变得非常简单和高效。 拆分每个页面(容器组件)和每个页面以包含其组件。 您也可以在名称组件外部有一个文件夹,以将所有全局组件保留在那里。 如果代码示例没有意义,请参考这里;)

Also you can see how the MERN project handles the server side rendering when the migration is done (another great feature you can use from React!) in order to make it done.

您还可以看到完成迁移后,MERN项目如何处理服务器端渲染(您可以从React!使用的另一个重要功能)来完成迁移。

I don’t have the index etc files in this structure its just focusing on the react components.

我在这种结构中没有索引etc文件,它只关注react组件。

创建您的第一个组件 (Create your first component)

Making your first component is relatively easy. I expect that you already familiar with react so I will just jump in the code. You can split your code to as many components you seem fits your needs. An example of a component is like the below. This is how I regularly switched small (Presentational) components of maybe a ul with data or each item of a ul.

制作第一个组件相对容易。 我希望您已经熟悉了react,所以我只是跳入代码。 您可以将代码拆分为看似满足您需求的尽可能多的组件。 组件的示例如下所示。 这就是我定期用数据或ul的每个项切换ul的小(Presentational)组件的方式。

This small components can now be imported to our project. When you define your module in the AngularJS app you can import the component and with react2angular dependency change it to AngularJS directive/component.

现在可以将这些小组件导入到我们的项目中。 在AngularJS应用中定义模块时,可以导入组件,并通过react2angular依赖项将其更改为AngularJS指令/组件。

.component("ratingsItem", react2angular(RatingsItem))

Now on the .html if you use <ratings-item></ratings-item> the component will load. Congrats this is your first react component to Angular !

现在在.html上,如果您使用<ratings-item> </ ratings-item>组件将被加载。 恭喜,这是您对Angular的第一个React组件!

Hope you didn’t got lost. Are you with me? … good. Remember!

希望你不会迷路。 你和我在一起吗? 很好。 记得!

This is my first writing so … be gentle with your judgement !
这是我的第一篇文章,所以……请谨慎对待您的判断!

Next step is that you want to change the whole module to react. This is going to be a container component in our react app. I split those in to pages. Before we proceed to that though we need to start using redux actions and reducers. This will help us in the next step when we will combine reducers with redux!

下一步是您要更改整个模块以做出React。 这将成为我们react应用程序中的容器组件。 我将它们分成几页。 在继续之前,我们需要开始使用redux动作和reducer。 当我们将reducer与redux结合使用时,这将对下一步有所帮助!

So in order to implement some redux for our container components first you will need to define your reducer and action for this Rating component. You can see the app structure above to see the naming and position of those in my project.

因此,为了对我们的容器组件实施一些还原,您将需要为此Rating组件定义减速器和操作。 您可以查看上面的应用程序结构 ,以查看其在我的项目中的命名和位置。

We will not explain actions and reducers in this topic as I keep as a fact that you are already familiar with Redux actions and reducers

我认为您已经熟悉Redux动作和缩减器,因此我们不会在本主题中解释动作和缩减器

My reducer looks like this.

我的减速器看起来像这样。

The Actions looks like this.

动作看起来像这样。

Simple! Doing two things just for the sake of testing that is working. you cna use your own.

简单! 只是为了进行测试而做两件事。 您可以使用自己的。

So this is going to be my ratings page. This is how my page is looking. you can also pass a “hi there” inside the div so you can be sure you have something without data. Again just for testing.

所以这将是我的评分页面。 这是我页面的外观。 您还可以在div中传递一个“ hi there”,这样就可以确保没有数据。 再次只是为了测试。

Now we will need to use ng-redux in order to create a store and pass that store down to our components. What we have to do is to combine all of our application reducers like we do in react so I created a separate file for that in order to use that in the future when i’ll remove AngularJS. I am calling this “Reducers” and it looks like this.

现在,我们将需要使用ng-redux来创建存储并将该存储传递给我们的组件。 我们要做的是像我们在react中一样将所有应用程序缩减程序组合在一起,因此我为此创建了一个单独的文件,以便将来在删除AngularJS时使用该文件。 我称之为“减速器”,它看起来像这样。

What it actually does is you define here all your application reducers in order to combine them and in the next step we “feed” those reducers to the redux for the state. You will see I only have Ratings for now but you can (and must) fill any new component along the way in here.

它的实际作用是在此处定义所有应用程序精简器,以便将它们组合在一起,然后在下一步中,将这些精简器“馈送”给状态的redux。 您会看到我目前只有等级,但是您可以(并且必须)在此处填充任何新组件。

Now we need to import the redux. In our main file when we define the whole application we import combined reduces, ngRedux, redux thunk and pass it as module dependency.

现在我们需要导入redux。 在我们的主文件中,当我们定义整个应用程序时,我们将合并的reduce,ngRedux,redux thunk合并并作为模块依赖项传递。

import ngRedux from "ng-redux";
import thunk from "redux-thunk";
import {RootReducer} from "./Reducers";
angular
    .module(
        "funkmartini",
        [
            ...,
            ngRedux,
            .....
        ]
     )
     .config(configApp)
     .run(runApp);

In your app configuration I am passing the $ngReduxProvider and I am creating my store. I am also passing the redux devtools if you want to put it in your project, if not just remove from the createStoreWith function.

在您的应用程序配置中,我通过了$ ngReduxProvider并创建了商店。 如果您想将redux devtools放到您的项目中,即使不是从createStoreWith函数中删除,我也要传递它。

$ngReduxProvider.createStoreWith(RootReducer, [thunk], [$window.__REDUX_DEVTOOLS_EXTENSION__()]);

You are all set now. Using the $ngRedux in your controllers you can now get the store of your application !

你们都准备好了。 现在,在控制器中使用$ ngRedux即可获取应用程序的存储!

总结到现在 (Sum up till now)

So we have made a small component. Then we refactored the whole module of Angular and created a container component to replace it. Now we wanted to pass some data and use redux and thats why we created the redux store to have an initial state and use or reducers define in the file to update it.

因此,我们做了一个小组成部分。 然后,我们重构了Angular的整个模块,并创建了一个容器组件来替换它。 现在,我们想传递一些数据并使用redux,这就是为什么我们创建redux存储以使其具有初始状态,并使用或在文件中定义的reducer对其进行更新的原因。

将该商店传递给组件! (Pass that store to components !!)

Because I was using the $stateProvider in Angular and I had something like the below. What I did is stop using an import of the template html page and I used directly the page of the react that i defined as a component before in AngularJS like we did previously. So I took this.

因为我在Angular中使用$ stateProvider,所以我有类似下面的内容。 我所做的是停止使用模板html页面的导入,并且像以前一样,我直接使用了之前在AngularJS中定义为组件的React页面。 所以我拿了这个。

function ratingsConfig($stateProvider) {
    $stateProvider
        .state("ratings", {
            url: "/ratings",
            views: {
                "main@settings": {
                    templateUrl: ratingsTemplate,
                    controller: "RatingsController"
                }
            }
        });
}

and change it to this.

并将其更改为此。

function ratingsConfig($stateProvider) {
    $stateProvider
        .state("ratings", {
            url: "/ratings",
            views: {
                "main@settings": {
                    template: `
                        <Ratings-Page store="store"></Ratings-Page>
                    `,
                    controller: "RatingsController"
                }
            }
        });
}

As you can see I am passing a store variable in the RatingsPage props. You imagine it right I am only using the RatingsController to get and pass that store. So the controller should look like this

如您所见,我正在RatingsPage属性中传递存储变量。 您可以想象对,我仅使用RatingsController来获取和传递该商店。 所以控制器应该看起来像这样

function ratingsController($scope, $ngRedux) {
    $scope.store = $ngRedux;
}

This way redux can identify that the store in the props its actually the store that needs in the connect() function.

通过这种方式,redux可以识别出道具中的商店实际上是其在connect()函数中所需的商店。

结论 (Conclusion)

Migrating AngularJS to React/redux is difficult and can take time but doesn’t have to be a nightmare. Once you’ve done with some basic configuration around the project it can be easily extended and slowly become a React project. Having to work as close to plain Javascript as possible is really great. Although it can take some time migrating I think in the long run its worth it. Suggestions that I skipped in this article is that you can start using some linting along the way (jslint, eslint — airbnb) as well and don’t forget to test the new components!

将AngularJS迁移到React / redux很困难,可能会花费一些时间,但不一定是噩梦。 一旦完成了围绕项目的一些基本配置,它就可以轻松扩展并慢慢成为一个React项目。 必须尽可能接近纯Javascript确实很棒。 尽管迁移可能需要一些时间,但从长远来看,我认为这样做值得。 我在本文中跳过的建议是,您也可以沿途开始使用某些棉绒(jslint,eslint-airbnb),并且不要忘记测试新组件!

Have fun and let me know how it goes!

玩得开心,让我知道如何发展!

翻译自: https://www.freecodecamp.org/news/angularjs-migration-to-react-redux-2d3bb3a7cc84/

 类似资料: