日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redux扩展工具_用鸭子扩展您的Redux App

發(fā)布時(shí)間:2023/11/29 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redux扩展工具_用鸭子扩展您的Redux App 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

redux擴(kuò)展工具

How does your front-end application scale? How do you make sure that the code you’re writing is maintainable 6 months from now?

您的前端應(yīng)用程序如何擴(kuò)展? 您如何確定您正在編寫的代碼從現(xiàn)在起6個(gè)月內(nèi)可維護(hù)?

Redux took the world of front-end development by storm in 2015 and established itself as a standard — even beyond the scope of React.

Redux在2015年席卷了前端開發(fā)領(lǐng)域,并確立了自己的標(biāo)準(zhǔn)-甚至超出了React的范圍。

At the company where I work, we recently finished refactoring a fairly large React codebase, adding redux instead of reflux.

在公司,我的工作,我們最近完成重構(gòu)一個(gè)相當(dāng)大的React的代碼庫(kù),將終極版,而不是回流 。

We did it because moving forward would have been impossible without a well structured application and a good set of rules.

我們這樣做是因?yàn)闆]有結(jié)構(gòu)良好的應(yīng)用程序和良好的規(guī)則,前進(jìn)將是不可能的。

The codebase is more than two years old, and reflux was there from the beginning. We had to change code that wasn’t touched in more than a year and was pretty tangled with the React components.

該代碼庫(kù)已有兩年多的歷史了,從一開始就存在回流 。 我們不得不更改了一年多沒有碰到的代碼,并且與React組件糾纏不清。

Based on the work we did on the project, I put together this repo, explaining our approach in organizing our redux code.

基于我們?cè)陧?xiàng)目上所做的工作,我整理了此倉(cāng)庫(kù) ,解釋了組織redux代碼的方法。

When you learn about redux and the roles of actions and reducers, you start with very simple examples. Most tutorials available today don’t go to the next level. But if you’re building something with Redux that’s more complicated than a todo list, you’ll need a smarter way of scaling your codebase over time.

當(dāng)您了解redux以及動(dòng)作和reduce的角色時(shí),您將從非常簡(jiǎn)單的示例開始。 今天可用的大多數(shù)教程都不會(huì)再上一個(gè)臺(tái)階。 但是,如果您要使用Redux構(gòu)建比待辦事項(xiàng)列表更復(fù)雜的東西,則需要一種更智能的方式來隨著時(shí)間擴(kuò)展代碼庫(kù)。

Someone once said that naming things is one of the hardest jobs in computer science. I couldn’t agree more. But structuring folders and organizing files is a close second.

曾經(jīng)有人說, 命名事物是計(jì)算機(jī)科學(xué)中最困難的工作之一。 我完全同意。 但是結(jié)構(gòu)化文件夾和組織文件緊隨其后。

Let’s explore how we approached code organization in the past.

讓我們探討一下過去如何進(jìn)行代碼組織。

功能與功能 (Function vs Feature)

There are two established approaches of structuring applications: function-first and feature-first.

有兩種建立應(yīng)用程序結(jié)構(gòu)的方法:“ 功能優(yōu)先”和“ 功能優(yōu)先” 。

One the left below you can see a function-first folder structure. On the right you can see a feature-first approach.

您可以在下面的左側(cè)看到功能優(yōu)先的文件夾結(jié)構(gòu)。 在右側(cè),您可以看到功能優(yōu)先的方法。

Function-first means that your top-level directories are named after the purpose of the files inside. So you have: containers, components, actions, reducers, etc.

“功能優(yōu)先”意味著您的頂級(jí)目錄是根據(jù)內(nèi)部文件的目的命名的。 因此,您擁有: 容器 , 組件 , 動(dòng)作 , 縮減器等等。

This doesn’t scale at all. As your app grows and you add more features, you add files into the same folders. So you end up with having to scroll inside a single folder to find your file.

這根本無法擴(kuò)展。 隨著應(yīng)用程序的增長(zhǎng)和添加更多功能,您將文件添加到相同的文件夾中。 因此,您最終不得不在單個(gè)文件夾中滾動(dòng)才能找到文件。

The problem is also about coupling the folders together. A single flow through your app will probably require files from all folders.

問題還在于將文件夾耦合在一起。 單次通過您的應(yīng)用程序流可能需要所有文件夾中的文件。

One advantage of this approach is that it isolates — in our case — React from redux. So if you want to change the state management library, you know which folders you need to touch. If you change the view library, you can keep your redux folders intact.

這種方法的一個(gè)優(yōu)勢(shì)是,在我們的案例中,它使React與Redux隔離開來。 因此,如果您想更改狀態(tài)管理庫(kù),則知道需要觸摸哪些文件夾。 如果更改視圖庫(kù),則可以保持redux文件夾完整。

Feature-first means that the top-level directories are named after the main features of the app: product, cart, session.

Feature-first意味著頂級(jí)目錄是根據(jù)應(yīng)用程序的主要功能命名的: product , cart , session 。

This approach scales much better, because each new feature comes with a new folder. But, you have no separation between the React components and redux. Changing one of them on the long run is a very tricky job.

這種方法的擴(kuò)展性更好,因?yàn)槊總€(gè)新功能都帶有一個(gè)新文件夾。 但是,React組件和redux之間沒有分隔。 從長(zhǎng)遠(yuǎn)來看,更改其中之一是一項(xiàng)非常棘手的工作。

Additionally you have files that do not belong to any feature. You end up with a folder common or shared, because you want to reuse code across many features in your app.

此外,您有不屬于任何功能的文件。 由于要在應(yīng)用程序中的許多功能之間重用代碼,因此最終得到一個(gè)公用或共享文件夾。

兩全其美 (The best of two worlds)

Although not in the scope of this article, I want to touch this single idea: always separate State Management files from UI files.

盡管不在本文討論范圍之內(nèi),但我還是想提出一個(gè)想法: 始終將狀態(tài)管理文件與UI文件分開。

Think about your application on the long run. Imagine what happens with the codebase when you switch from React to another library. Or think how your codebase would use ReactNative in parallel with the web version.

從長(zhǎng)遠(yuǎn)來看您的應(yīng)用程序。 想象一下,當(dāng)您從React切換到另一個(gè)庫(kù)時(shí),代碼庫(kù)會(huì)發(fā)生什么。 或者考慮您的代碼庫(kù)如何將ReactNative與Web版本并行使用。

Our approach starts from the need to isolate the React code into a single folder — called views — and the redux code into a separate folder — called redux.

我們的方法首先需要將React代碼隔離到一個(gè)單獨(dú)的文件夾(稱為視圖)中,并將redux代碼隔離到一個(gè)單獨(dú)的文件夾中,稱為redux。

This first level split gives us the flexibility to organize the two separate parts of the app completely different.

第一級(jí)拆分使我們可以靈活地組織完全不同的應(yīng)用程序的兩個(gè)獨(dú)立部分。

Inside the views folder, we prefer a function-first approach in structuring files. This feels very natural in the context of React: pages, layouts, components, enhancers etc.

在views文件夾中,我們更喜歡在結(jié)構(gòu)化文件時(shí)采用功能優(yōu)先的方法。 在React的上下文中,這感覺很自然: 頁面 , 布局 , 組件,增強(qiáng)器等。

To not go crazy with the number of files in a folder, we may have a feature based split inside each of these folders.

為了避免困擾一個(gè)文件夾中的文件數(shù)量,我們可能在每個(gè)文件夾中都有基于功能的拆分。

Then, inside the redux folder…

然后,在redux文件夾中…

輸入重新鴨子 (Enter re-ducks)

Each feature of the application should map to separate actions and reducers, so it makes sense to go for a feature-first approach.

應(yīng)用程序的每個(gè)功能都應(yīng)映射到單獨(dú)的操作和簡(jiǎn)化程序,因此采用功能優(yōu)先的方法是有意義的。

The original ducks modular approach is a nice simplification for redux and offers a structured way of adding each new feature in your app.

原始的ducks模塊化方法是redux的一個(gè)很好的簡(jiǎn)化,并提供了一種結(jié)構(gòu)化的方式來在您的應(yīng)用程序中添加每個(gè)新功能。

Yet, we wanted to explore a bit what happens when the app scales. We realized that a single file for a feature becomes too cluttered and hard to maintain on the long run.

但是,我們想探索一下應(yīng)用擴(kuò)展時(shí)會(huì)發(fā)生什么。 我們意識(shí)到,功能的單個(gè)文件變得過于混亂,從長(zhǎng)遠(yuǎn)來看很難維護(hù)。

This is how re-ducks was born. The solution was to split each feature into a duck folder.

這就是再鴨的誕生 。 解決方案是將每個(gè)功能拆分到一個(gè)鴨子文件夾中。

duck/ ├── actions.js ├── index.js ├── operations.js ├── reducers.js ├── selectors.js ├── tests.js ├── types.js ├── utils.js

A duck folder MUST:

鴨子文件夾必須:

  • contain the entire logic for handling only ONE concept in your app, ex: product, cart, session, etc.

    包含用于僅在您的應(yīng)用中處理一個(gè)概念的完整邏輯,例如: product , cart , session等。

  • have an index.js file that exports according to the original duck rules.

    有一個(gè)index.js文件,該文件根據(jù)原始的鴨子規(guī)則導(dǎo)出。

  • keep code with similar purpose in the same file, such as reducers, selectors, and actions

    將目的相似的代碼保存在同一文件中,例如reducers , selectors和action

  • contain the tests related to the duck.

    包含與鴨子有關(guān)的測(cè)試 。

For this example, we haven’t used any abstraction built on top of redux. When building software, it’s important to start with the least amount of abstractions. This way, you make sure that the cost of your abstractions doesn’t outweigh the benefits.

對(duì)于此示例,我們沒有使用基于redux構(gòu)建的任何抽象。 在構(gòu)建軟件時(shí),從最少的抽象量開始很重要。 這樣,您可以確保抽象的成本不會(huì)超過收益。

If you need to convince yourself that abstractions can be bad, watch this awesome talk by Cheng Lou.

如果您需要使自己相信抽象可能是不好的,請(qǐng)觀看Cheng Lou的精彩演講 。

Let’s see what goes into each file.

讓我們看看每個(gè)文件中包含的內(nèi)容。

種類 (Types)

The types file contains the names of the actions that you are dispatching in your application. As a good practice, you should try to scope the names based on the feature they belong to. This helps when debugging more complex applications.

類型文件包含要在應(yīng)用程序中分派的動(dòng)作的名稱。 作為一種好習(xí)慣,您應(yīng)該嘗試根據(jù)名稱所屬的功能來確定名稱的范圍。 這有助于調(diào)試更復(fù)雜的應(yīng)用程序。

const QUACK = "app/duck/QUACK"; const SWIM = "app/duck/SWIM";export default {QUACK,SWIM };

動(dòng)作 (Actions)

This file contains all the action creator functions.

該文件包含所有動(dòng)作創(chuàng)建器功能。

import types from "./types";const quack = ( ) => ( {type: types.QUACK } );const swim = ( distance ) => ( {type: types.SWIM,payload: {distance} } );export default {swim,quack };

Notice how all the actions are represented by functions, even if they are not parametrized. A consistent approach is more than needed in a large codebase.

請(qǐng)注意,即使未對(duì)參數(shù)進(jìn)行參數(shù)設(shè)置,所有動(dòng)作如何由函數(shù)表示。 在大型代碼庫(kù)中,一致的方法已遠(yuǎn)遠(yuǎn)超過了所需。

運(yùn)作方式 (Operations)

To represent chained operations you need a redux middleware to enhance the dispatch function. Some popular examples are: redux-thunk, redux-saga or redux-observable.

為了表示鏈?zhǔn)讲僮?#xff0c;您需要一個(gè)Redux 中間件來增強(qiáng)調(diào)度功能。 一些流行的示例是: redux-thunk , redux-saga或redux-observable 。

In our case, we use redux-thunk. We want to separate the thunks from the action creators, even with the cost of writing extra code. So we define an operation as a wrapper over actions.

在我們的例子中,我們使用redux-thunk 。 我們希望將動(dòng)作與動(dòng)作創(chuàng)建者區(qū)分開來,即使付出編寫額外代碼的代價(jià)。 因此,我們將操作定義為動(dòng)作的包裝。

If the operation only dispatches a single action — doesn’t actually use redux-thunk — we forward the action creator function. If the operation uses a thunk, it can dispatch many actions and chain them with promises.

如果該操作僅調(diào)度單個(gè)操作-實(shí)際上未使用redux-thunk-我們將轉(zhuǎn)發(fā)操作創(chuàng)建者函數(shù)。 如果操作使用重?fù)?#xff0c;則可以分派許多操作并將它們與承諾鏈接在一起。

import actions from "./actions";// This is a link to an action defined in actions.js. const simpleQuack = actions.quack;// This is a thunk which dispatches multiple actions from actions.js const complexQuack = ( distance ) => ( dispatch ) => {dispatch( actions.quack( ) ).then( ( ) => {dispatch( actions.swim( distance ) );dispatch( /* any action */ );} ); }export default {simpleQuack,complexQuack };

Call them operations, thunks, sagas, epics, it’s your choice. Just find a naming convention and stick with it.

稱它們?yōu)椴僮?#xff0c;重?fù)?#xff0c;薩加斯,史詩,這是您的選擇。 只要找到一個(gè)命名約定并堅(jiān)持下去即可。

At the end, when we discuss the index, we’ll see that the operations are part of the public interface of the duck. Actions are encapsulated, operations are exposed.

最后,當(dāng)我們討論index時(shí) ,我們將看到操作是Duck的公共接口的一部分。 動(dòng)作被封裝,操作被公開。

減速器 (Reducers)

If a feature has more facets, you should definitely use multiple reducers to handle different parts of the state shape. Additionally, don’t be afraid to use combineReducers as much as needed. This gives you a lot of flexibility when working with a complex state shape.

如果特征具有更多的構(gòu)面,則絕對(duì)應(yīng)使用多個(gè)化簡(jiǎn)器來處理狀態(tài)形狀的不同部分。 此外,不要害怕根據(jù)需要使用CombineReducers 。 在處理復(fù)雜的狀態(tài)形狀時(shí),這為您提供了很大的靈活性。

import { combineReducers } from "redux"; import types from "./types";/* State Shape {quacking: bool,distance: number } */const quackReducer = ( state = false, action ) => {switch( action.type ) {case types.QUACK: return true;/* ... */default: return state;} }const distanceReducer = ( state = 0, action ) => {switch( action.type ) {case types.SWIM: return state + action.payload.distance;/* ... */default: return state;} }const reducer = combineReducers( {quacking: quackReducer,distance: distanceReducer } );export default reducer;

In a large scale application, your state tree will be at least 3 level deep. Reducer functions should be as small as possible and handle only simple data constructs. The combineReducers utility function is all you need to build a flexible and maintainable state shape.

在大型應(yīng)用程序中,您的狀態(tài)樹將至少深3層。 Reducer函數(shù)應(yīng)盡可能小,并且僅處理簡(jiǎn)單的數(shù)據(jù)構(gòu)造。 CombineReducers實(shí)用程序功能是構(gòu)建靈活且可維護(hù)的狀態(tài)形狀所需的全部。

Check out the complete example project and look how combineReducers is used. Once in the reducers.js files and then in the store.js file, where we put together the entire state tree.

查看完整的示例項(xiàng)目,并查看如何使用CombineReducers 。 一次進(jìn)入reducers.js文件,然后進(jìn)入store.js文件,在這里我們將整個(gè)狀態(tài)樹放在一起。

選擇器 (Selectors)

Together with the operations, the selectors are part of the public interface of a duck. The split between operations and selectors resembles the CQRS pattern.

選擇器與操作一起是鴨子公共接口的一部分。 操作和選擇器之間的劃分類似于CQRS模式 。

Selector functions take a slice of the application state and return some data based on that. They never introduce any changes to the application state.

選擇器函數(shù)獲取應(yīng)用程序狀態(tài)的一部分,并根據(jù)該狀態(tài)返回一些數(shù)據(jù)。 他們從不對(duì)應(yīng)用程序狀態(tài)進(jìn)行任何更改。

function checkIfDuckIsInRange( duck ) {return duck.distance > 1000; }export default {checkIfDuckIsInRange };

指數(shù) (Index)

This file specifies what gets exported from the duck folder. It will:

此文件指定從duck文件夾導(dǎo)出的內(nèi)容。 它會(huì):

  • export as default the reducer function of the duck.

    默認(rèn)情況下導(dǎo)出鴨子的reduce功能。
  • export as named exports the selectors and the operations.

    導(dǎo)出為命名,導(dǎo)出選擇器和操作。
  • export the types if they are needed in other ducks.

    如果其他鴨子需要它們,則將其導(dǎo)出。
import reducer from "./reducers";export { default as duckSelectors } from "./selectors"; export { default as duckOperations } from "./operations"; export { default as duckTypes } from "./types";export default reducer;

測(cè)驗(yàn) (Tests)

A benefit of using Redux and the ducks structure is that you can write your tests next to the code you are testing.

使用Redux和ducks結(jié)構(gòu)的好處是您可以在要測(cè)試的代碼旁邊編寫測(cè)試。

Testing your Redux code is fairly straight-forward:

測(cè)試您的Redux代碼非常簡(jiǎn)單:

import expect from "expect.js"; import reducer from "./reducers"; import actions from "./actions";describe( "duck reducer", function( ) {describe( "quack", function( ) {const quack = actions.quack( );const initialState = false;const result = reducer( initialState, quack );it( "should quack", function( ) {expect( result ).to.be( true ) ;} );} ); } );

Inside this file you can write tests for reducers, operations, selectors, etc.

在此文件中,您可以編寫用于化簡(jiǎn),操作,選擇器等的測(cè)試。

I could write a whole different article about the benefits of testing your code, there are so many of them. Just do it!

我可以寫一篇關(guān)于測(cè)試代碼的好處的不同文章,其中有很多。 去做就對(duì)了!

就是這樣 (So there it is)

The nice part about re-ducks is that you get to use the same pattern for all your redux code.

關(guān)于重新鴨子的好處是,您可以對(duì)所有redux代碼使用相同的模式。

The feature-based split for the redux code is much more flexible and scalable as your application codebase grows. And the function-based split for views works when you build small components that are shared across the application.

隨著您的應(yīng)用程序代碼庫(kù)的增長(zhǎng),redux代碼的基于功能的拆分更加靈活和可擴(kuò)展。 當(dāng)您構(gòu)建在應(yīng)用程序之間共享的小型組件時(shí),基于視圖的基于功能的拆分將起作用。

You can check out a full react-redux-example codebase here. Just keep in mind that the repo is still under active development.

您可以在此處查看完整的react-redux-example代碼庫(kù)。 請(qǐng)記住,回購(gòu)仍在積極開發(fā)中。

How do you structure your redux apps? I’m looking forward to hearing some feedback on this approach I’ve presented.

您如何構(gòu)造您的redux應(yīng)用程序? 我期待聽到有關(guān)我提出的這種方法的一些反饋。

If you found this article useful, click on the green heart below and I will know my efforts are not in vain.

如果您發(fā)現(xiàn)本文有用,請(qǐng)單擊下面的綠色心臟,我將知道我的努力沒有白費(fèi)。

翻譯自: https://www.freecodecamp.org/news/scaling-your-redux-app-with-ducks-6115955638be/

redux擴(kuò)展工具

總結(jié)

以上是生活随笔為你收集整理的redux扩展工具_用鸭子扩展您的Redux App的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。