12 ms·
Reasons to Learn Redux as a JavaScript Developer
- acemarke 7y agoI'm a Redux maintainer. I agree with the points Robin made, and want to toss out a few additional bits of info. There's been a lot of chatter on social media over the last couple years suggesting Redux is dying or no longer needed. While it's true that there's a number of other options available, and that there's not as much _need_ to use Redux right away as there used to be, there's still plenty of good reasons to use Redux. In addition, Redux continues to be very widely used, and I've seen quite a few major apps choose to use it over the last year. I talked about these aspects in my Reactathon 2019 talk on "The State of Redux" [0] and my post "Redux - Not Dead Yet!" [1]. We recently released a new official package called Redux Toolkit [2], which includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once. It's now our recommended approach for writing Redux logic. It's also written in TypeScript, and the API is designed to provide a great experience in TS apps. We're currently working on an ongoing major rewrite of the Redux core docs [3], which has several goals: updating content to better match today's target dev audience (removing references to "Flux", etc), simplifying explanations, encouraging easier patterns, and adding additional content and guidance on real-world usage. As part of that, we've added a new "Style Guide" page [4], which has our recommended patterns and practices for writing good Redux code. We're specifically emphasizing and recommending patterns that simplify the amount of code you have to write, like using Immer for immutable updates, using the "ducks" structure for files and logic, treating actions as "events" rather than "setters", and so on. Earlier this year, we also released new versions of React-Redux. v7.0 was a complete rewrite of the internals to improve performance, and v7.1 added a new React hooks API [5] as an alternative to the classic `connect()` API. If you're interested in some of the behind-the-scenes details on how these libraries have evolved, see my posts "The History and Implementation of React-Redux" [5] and "Redux Toolkit 1.0" [6]. If anyone's got any questions, ask away! [0] https://blog.isquaredsoftware.com/2019/03/presentation-state-of-redux/ https://blog.isquaredsoftware.com/2019/03/presentation-state... [1] https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/ https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet... [2] https://redux-toolkit.js.org https://redux-toolkit.js.org [3] https://github.com/reduxjs/redux/issues/3592 https://github.com/reduxjs/redux/issues/3592 [4] https://redux.js.org/style-guide/style-guide https://redux.js.org/style-guide/style-guide [5] https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/ https://blog.isquaredsoftware.com/2018/11/react-redux-histor... [6] https://blog.isquaredsoftware.com/2019/10/redux-starter-kit-1.0/ https://blog.isquaredsoftware.com/2019/10/redux-starter-kit-...
- guu 7y agoIn the official FAQ it says something to the effect of “You’ll know when you need redux.” Recently there’s some backlash surrounding the use of redux and I’d be interested in hearing about projects (preferably open source so we can see the code) that were using the built in react state management tools and came to the conclusion they were not sufficient.
- modernerd 7y agoWordPress's Gutenberg editor is built on top of Redux: https://developer.wordpress.org/block-editor/packages/packages-data/#comparison-with-redux https://developer.wordpress.org/block-editor/packages/packag...
- weeksie 7y agoThis is disappointing. Partially for bikeshed reasons, but also for practical ones. Redux thunk is an anti pattern as far as I'm concerned but you're including it by default? Why? Just because it's the first (bad) decision people make when trying to handle async code doesn't mean it's the one that should be canonized. The createAction function is unnecessarily verbose and the createReducer function obscures more than it abstracts.
- acemarke 7y agoI find your concerns very confusing. In order: Thunks are the most widely used middleware by a large margin [0], and we have frequently received complaints that there is no async middleware included in the Redux store by default. Thunks were in fact part of the store during the original development phase [1], but were made separate once the middleware API was defined [2]. Thunks are effectively the minimum viable way to write async logic that has access to interacting with the Redux store, so we include that in RTK out of the box to make that possible. Sagas, observables, and other similar middleware are far too heavyweight and complex for us to endorse as the default async approach. I also strongly disagree that thunks are an "anti-pattern", and find them to be a highly useful tool (and especially so now that `async/await` syntax makes it even easier to write more complicated async logic in a readable form) [3]. You are always welcome to add another middleware or disable thunks as part of the store setup process instead if you want. I don't see how this: const addTodo = createAction("todos/add") is more verbose than this: const addTodo = (text) => { return { type: "todos/add", payload: text } } We've had a version of `createReducer` shown in the "Reducing Boilerplate" docs page [4] for years, and there are literally hundreds of similar "lookup table"-type utilities out there. Including this in RTK is a no-brainer. It's even more valuable, because ours uses Immer inside to let you write "mutative" immutable update logic instead of having to nest spread operators. I don't see how this is "obscuring" anything. Finally, our recommendation is that most of the time you shouldn't even be calling `createAction` and `createReducer` yourself. Instead, you should be using the `createSlice` function [5], which automatically generates action creators and action types for you, and calls the other two functions internally. [0] Slide 38 in https://blog.isquaredsoftware.com/2017/09/presentation-might-need-redux-ecosystem/ https://blog.isquaredsoftware.com/2017/09/presentation-might... [1] https://github.com/reduxjs/redux/issues/1 https://github.com/reduxjs/redux/issues/1 [2] https://github.com/reduxjs/redux/pull/63#issuecomment-110575809 https://github.com/reduxjs/redux/pull/63#issuecomment-110575... [3] https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-thunks-sagas-abstraction-and-reusability/ https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-th... [4] https://redux.js.org/recipes/reducing-boilerplate#generating-reducers https://redux.js.org/recipes/reducing-boilerplate#generating... [5] https://redux-toolkit.js.org/api/createSlice https://redux-toolkit.js.org/api/createSlice
- csande17 7y agoSomething I've wondered about the "immutable updates" pattern discussed in the article: do JavaScript engines optimize it somehow? On its face, it seems like it would turn a constant-time "favorite post X" operation into a linear-time "create a copy of the array of all the posts, replacing post X with a copy of post X where 'favorited' is true" operation. Or do developers just assume that their UI code won't ever need to scale to large numbers of items? (Is this why JIRA's web UI is so slow when you have a couple thousand open tickets?)
- acemarke 7y agoThere are definitely costs to doing immutable updates of objects and arrays. The engine has to allocate a new object in memory, copy over all the existing keys, and copy any new keys / values you're assigning. For very large objects, yes, this can become noticeable. But, for most apps, this isn't a concern given the kinds of data and state updates that are common. There's a specific library called Immutable.js, which implements some complex internal data structures to optimize copying objects. However, the library is relatively large, and complicated some common usage patterns. My opinion is that it's rarely worth using that lib.
- viraptor 7y ago> Or do developers just assume that their UI code won't ever need to scale to large numbers of items? If you have enough items that a copy of all attributes is noticeable to the user, the user will never realistically see those items. (We'd be talking about thousands of them minimum) Or alternatively you're loading A LOT of data per item. Either way, the issue in almost every single case is not that the copy takes too long. I mena, there are edge cases like an endless list of small items (twitter?) which someone scrolls for a long time and then makes a modification. But then you should know it's potentially a REALLY long list you need to handle.
- fyp 7y agoMost functional languages have immutable persistent data structures that don't require a linear copy and are fairly efficient. For example in clojure, sequences are implemented as 32-ary tries so insert/delete/update to any particular index will only cost around sizeOfNode * numParents=32 * log_32(n). This comes with a cost that indexing is now log_32(n) but it's usually a fair price to pay. In javascript, immutable.js implement these same ideas (as least according to these talks where they talk about index tries and hash array mapped tries: https://youtu.be/I7IdS-PbEgI?t=456 https://youtu.be/I7IdS-PbEgI?t=456) If you want native support, javascript engines are actually free to swap out their implementation of arrays! I know they already do depending on whether they think your array is sparse("holey") or not: https://github.com/v8/v8/blob/8.1.81/src/builtins/builtins-array.cc#L887 https://github.com/v8/v8/blob/8.1.81/src/builtins/builtins-a.... I also vaguely recall someone saying that unshift (push to front) is automatically optimized by switching to a deque/circular buffer but I might be remembering wrong. Anyway, they can make these optimizations in a distant future but I don't think do today.
- FpUser 7y agoMy brain I guess works in a different way. I could never truly understand/appreciate value of the Redux for state management (well except that it is better then nothing). For this type of things I've always used one or the other implementation of State Machine pattern. Seems way more clear to me. It is not just about JavaScript. State management is a part of many applications and State Machine is a nice paradigm to work with. At least for my taste.
- acemarke 7y agoThe key values of Redux are separating state update logic from the rest of the app, emphasizing writing as much logic as possible as pure functions that are easy to test, and enabling developers to better understand when, where, why, and how their state is changing over time. Note that it's entirely possible to write your reducer logic as state machines, and in fact we explicitly encourage that : https://redux.js.org/style-guide/style-guide#treat-reducers-as-state-machines https://redux.js.org/style-guide/style-guide#treat-reducers-...
- FpUser 7y agoIn my opinion State Machine is sufficient on it's own. To me reducers seem superfluous and in fact distracting from actually managing state. But as already said it is my own opinion coming from my own experience. We do not need to convince each other
- tempsy 7y agoRedux is not that hard to learn so why not? Why spend more time debating whether to learn something than just learn it?
- Supermancho 7y agoIt's hard enough. I haven't needed it in developing/contributing to my own frameworks and there's an infinite amount of things to look into. Right from the Redux docs (https://redux.js.org/faq/general/#when-should-i-use-redux https://redux.js.org/faq/general/#when-should-i-use-redux) - the link https://gedd.ski/post/what-not-to-learn/ https://gedd.ski/post/what-not-to-learn/
- tempsy 7y agoDunno. Perhaps there’s more functionality than the core but all it is is a plain JavaScript object that you “update” that you can access from different parts of your app. It really isn’t that complicated.
- jkoudys 7y agoI'd argue that Redux is so downright trivial to learn, there's a good chance that you already know it. The part that takes a bit of study is learning flux. You should already know how a reducer function works from Arrays, and all that makes the Redux approach special is your accumulator is read-only. The implications and advantages of all this are huge and take some time to really appreciate, but you shouldn't lose much time being confused and unproductive. The flux concepts of one-way data flow, action creators, etc. are the bigger ideas that take some study.
- sansnomme 7y agoRedux is tremendously verbose though. Message passing isn't attractive when the state space is big.
- vedran 7y agoAgreed. I much prefer the style of rematch[1] where you bind directly to the actions rather than creating a constant to check for in a switch statement [1] https://github.com/rematch/rematch https://github.com/rematch/rematch
- acemarke 7y agoThat's specifically why we've created our new official Redux Toolkit package - to simplify the incidental complexity that is not actually part of Redux itself. Try it for yourself : https://redux-toolkit.js.org https://redux-toolkit.js.org
- sandGorgon 7y agoWhat about the built-in Context api ?
- acemarke 7y agoContext is a useful tool, but its only purpose is to make value accessible to deeply nested components. It's not even a state management tool - you have to manage whatever state you want to put into that context, by yourself. The useState and useReducer hooks start to resemble Redux a bit more when used together with context, but they definitely do not replace Redux. For more details, see these posts : - https://daveceddia.com/context-api-vs-redux/ https://daveceddia.com/context-api-vs-redux/ - https://www.simplethread.com/cant-replace-redux-with-hooks/ https://www.simplethread.com/cant-replace-redux-with-hooks/ - https://staleclosures.dev/from-redux-to-hooks-case-study/ https://staleclosures.dev/from-redux-to-hooks-case-study/ - https://medium.com/javascript-scene/do-react-hooks-replace-redux-210bab340672 https://medium.com/javascript-scene/do-react-hooks-replace-r... - https://dev.to/chrisachard/can-you-replace-redux-with-react-hooks-20gm https://dev.to/chrisachard/can-you-replace-redux-with-react-...
- zabana 7y agoAbsolutely. For most projects it is more than enough. If you have a basic CRUD app with token authentication you can get away with using that. There has been better form support thanks to new libraries coming out recently so I don't see reason to learn redux is, as was pointed out by other commenters, very verbose and requires a lot of boilerplate code to get started. The context API is baked in, no external lib required. If you can afford to update your react codebase to the latest version without major breaking changes I would totally migrate to the context API.
- leetrout 7y agoMobX does not get enough love and has been around for a while https://mobx.js.org/README.html https://mobx.js.org/README.html
- fyp 7y agoI found the philosophy communicated by mobx-state-tree to be a lot clearer than redux (particularly stuff around patches, snapshots and async flows): https://mobx-state-tree.js.org/intro/philosophy https://mobx-state-tree.js.org/intro/philosophy
- sansnomme 7y agoCheck out Svelte. Essentially reactivity baked into the compiler so you don't have to use observables everywhere.
- leetrout 7y agoSecond time it’s been mentioned in as many days. Are you actively using it?
- sansnomme 7y agoYes it is pretty straightforward though the project is still growing and suffering from the usual growing pains. Think docs that has plenty of room for improvement, insufficient example projects and components. On the up side the team responds quickly, the concepts are ridiculously simple compared to Redux and there's a burgeoning community around it. E.g. https://sveltematerialui.com/ https://sveltematerialui.com/ The Next.js equivalent for SSR is Sapper: https://sapper.svelte.dev/ https://sapper.svelte.dev/ Note the creator of Svelte is the same guy who created the Rollup bundler so pretty much everything comes with dual configs for both Rollup and Webpack.
- Kiro 7y agoOne of the main reasons I'm using Redux is because of the global store. If I understand the docs correctly this is how you do it in Svelte: https://svelte.dev/examples#writable-stores https://svelte.dev/examples#writable-stores What's up with that? A strange semi-singleton where you need to use writable(0)? Also strange that subscribe return unsubscribe. Doesn't seem very intuitive.
- Karupan 7y agoRedux was such a mental overhead for me when I started out with it. The amount of boilerplate code that I had to write for the project I worked on was very frustrating. What helped me truly understand the concept was Elm. These days I ask junior devs to learn Elm for a few days. We still use Redux, I will not choose it for new projects.
- acemarke 7y agoPlease try out our new official Redux Toolkit package, which will help simplify your Redux logic considerably: https://redux-toolkit.js.org https://redux-toolkit.js.org
- fastball 7y agoor Rematch. http://rematch.github.io/ http://rematch.github.io/
- banachtarski 7y agoRight see, this is what all redux proponents advocate. Every redux project I see is chock-ful of "extras" to make redux workable, and this changes from season to season. If this isn't an architectural smell, I don't know what is.
- bauerd 7y agoNot sure why different libraries would be an architectural smell. Not only Redux projects vary greatly in what they bolt onto their state management. I've used Redux successfully on its own. The dataflow pattern it mandates is important, not the concrete implementation.
- egeozcan 7y agoYou can use the built-in IoC controller or Autofac or ServiceStack or whatever you want along with ASP.NET Core projects. I don't think it is architectural smell at all. Also I find classifying people as Redux-proponents funny. It's not a camp, or at least not supposed to be one.
- banachtarski 7y agoAnecdotally, Redux was absolutely awful to work with. Want a project chockful of middleware to make it passably usable? Use Redux. With all due respect to the Redux team, I simply don't think Redux scales in large applications. The "defaults" are insanely unproductive and encourage developers to cram tons of state in some global pile of state-soup just to claw back conveniences they lost. Monadic transformers and pure state transitions - great ideas in principle, carried way too far here in an ecosystem where the rest of the language and libraries rely on and use mutable state. Not to mention the lost performance, bloat for code that would be considerably shorter, and more disadvantages. No thanks Redux, no thanks :/
- tempsy 7y agoPerhaps you’re using it wrong. It’s tiny. All you do is manipulate a JavaScript object that holds some state that different parts of your app can access. It’s not much more complicated than that.
- banachtarski 7y ago2.4 kB minified isn't "tiny" but sure, blame the user.
- StuffedParrot 7y agoI was under the impression redux is basically a message bus plus some sugar. Is that wrong?
- tempsy 7y agoNo you’re right. I find the comments deriding Redux as some bloated beast to be amusing...it’s just a thing that lets you read and update a plain javascript object that different parts of your app can access. People making things more complicated than they are is really a disease in the dev community.
- banachtarski 7y ago
- gunn 7y agoHere's the library I wrote to replace redux for myself: https://github.com/gunn/pure-store https://github.com/gunn/pure-store It's the simplest API I could think of, has excellent type support, and handles immutability for you.
- bcherny 7y agoLooks very similar to Undux! https://undux.org/ https://undux.org/ Then again, who hasn’t built a state management framework for React?
- will123195 7y agoNice. My take on the simplest possible API: https://github.com/will123195/venti https://github.com/will123195/venti
- lioeters 7y agoThank you for pure-store, I'm surprised it hasn't attracted more attention! The API is perfectly small and straight-forward, it's close to the ideal I imagine. For a few years I've been using a similarly tiny library I wrote to reduce Redux's verbosity, but I may migrate to pure-store as it's even smaller and gets to the essence of state management. Seeing the popularity of React hooks and Redux+friends, I know I'm in the minority of people who lament the direction they're going. I'm secretly hoping for a "destructuring" of the React ecosystem into more generic concepts/libraries/modules that work with or without React, carrying on the lessons learned but implemented as simple and independent as possible. To me, pure-store (and immer for sure) is one of those libraries that point the way to a better future.
- hnbreak 7y agoRedux is a mixed bag but I'd say it's one of the most elegant ways to handle state. Biggest problem and reason why people (me included at the beginning) don't like Redux, you should know when you need it and you should use some abstraction layer (eg RTK). One cause could be the docs: while the maintainer try their best to educate a lot (also in this thread paired with interesting link building strategies), there is not quick and easy way to get into Redux. If you start with RTK's docs, you don't understand everything. Then, you need to read the Redux docs, then again back and forth. And this just takes too long to grok an actual simple API. One easy indicator for Redux or not: does your app need kind of an undo feature, then you should dive into Redux and I'll promise you. there is no other way to do this in such a sane, maintainable way.
- acemarke 7y agoAs mentioned elsewhere in the thread, we're working on a major rewrite of the Redux core docs. If you've got any specific suggestions on how we can improve them, please let me know. When you say "no quick and easy way to get started", are you referring to code or docs? In terms of explanations, RTK is currently documented as a separate layer on top of Redux, because that's really what it is. So yes, we do assume that folks have learned what Redux is and how to use it already, and RTK is then a faster and better way to write Redux logic instead of doing everything "by hand". As part of the core docs rewrite, we do intend to completely redo the tutorial sequence, and we'll be introducing RTK somewhere in the tutorials and encouraging its use.
- hnbreak 7y agoI meant the docs. It's like decades ago like when you wanted to learn Rails. Then somebody said stop! First learn Ruby... This is not how people learn. There's too much time between learning and trying, so there's no proper and face-paced feedback loop. Let's try to get into somebody's head who's ok in react and slowly wants to get into state management but having no clue of nothing: His mind: - Ok, where should I start? - Which is the best? Mobx, redux, just ContextProvider or local state?? The poor guys falls into the rabbit hole and reads Reddit, HN, Github issues for hours, still not sure what to do; 2 hours later - Ok, let's try redux, for whatever reason, the maintainers seem to be quite active The poor guy tries to decide if he should go just with redux/react-redux or rtk; former because it is good to understand the foundation, latter good because just to avoid boilerplate and that's what this acemark is promoting everywhere. The guy is still overwhelmed and don't forget doing decision is hard; it's one of the biggest struggles for humans - Ok, I guess I need to start with redux because it's the foundation. He sees all the theory, new terms, the boilerplate and there's no fast-paced feedback loop; he just think heck and checks out mobx, 4 hours later - Man mobx is even more weird, totally unstructured and while mobx's maintainer seems to be a nice guy, my gut feeling is: stay away - Let's check out npmtrends, oh great, npmtrends shows that people also don't like mobx, cool, it has much less traction, decision made, nice - So, let's try redux again, maybe this time I start with RTK We know what happens, RTK has better feedback loops but w/o the basic knowledge of redux he will struggle, 6 hours later after jumping back and forth the both docs - Lets stop here, tomorrow is another day. He is out of flow, motivation is down, the next day he doesn't continue because the whole experience didn't feel good, he writes a post on HN that redux sucks steel and maybe looks the next week again on it The situation is a bit like with kubernetes; until you have proper feedback loops with k8s you need days, with new k8s distros this got better but the biggest bummer are the k8s docs, too much, too verbose, so many new terms, no feedback loops at all and every k8s examples has minimum 100kb yamls. What would be great and I know that writing good docs is much harder than actual code: One and only piece which the reader should read first, which teaches him redux foundation, react-redux boilerplate and rtk within max 2 hours. After that he should have a working example AND should have understood it. No links to other resources, no nothing. This main piece should be linked everywhere in the Github readmes of all redux relates projects in bold and h1 READ OUR MAIN PIECE FIRST, on all the doc pages and in all forum posts. I mean look at your post's footer in this thread: so many links, why? You need one entry point. RTK could be the entry point, it just needs a bit more flesh on redux and should be declared as the entry point of redux. There's one disadvantage though: with RTK as entry you'd kill the ecosystem around redux but IDK if you did this anyway by declaring RTK the standard way. And you would have a lot of redundant docs with redux/react-redux. Or maybe we need to merge all because maintaining redundant docs is just too much for an OSS project. Whatever, all not easy but there must be a way because redux is the most underrated thing in the frontend world, it's def the best state management and RTK is a nice and long deserved abstraction.
- larusso 7y agoI honestly have no clue about Redux. I know a bit about react and used Mobx but I’m not a huge fan. When it comes to state managers and especially bigger frameworks with best practice patterns I get reminded a lot about PureMVC. This was the framework in the late 2000th that claimed to solve everything because it’s so simple and slim. But with a bigger application the whole boilerplate setup exploded. And don’t get me started with PureMVC pipes etc. Reading the comments here sounds like Redux has kind of the same issues.
- jtdev 7y agoRedux = functional zealotry
- sktrdie 7y agoThe issue with Redux is that a dispatch() and hence a state update causes a synchronous (hence blocking) update of the view. Andrew Clark better explains the difference in this tweet: https://twitter.com/acdlite/status/1195453776217296896 https://twitter.com/acdlite/status/1195453776217296896 > Redux architecture depends on the ability to block the main thread until rendering is complete. Once you make rendering non-blocking, your store is no longer synchronized with the UI. Leading to data races and inconsistencies. Many view layers are moving towards non-blocking rendering as they need to account for things such as different priorities based on what the user needs: for instance a user typing needs larger priority than a banner showing. Once it is non-blocking it's hard to keep a store and several UIs elements in sync. For instance your store might say isLoading:true but the UI might not show that since it's rendering/working another higher-priority element on the screen. And then you might have another view that depends on the isLoading:true which causes another thing to appear on the screen before the other element is shown... all this leads to inconsistencies and race conditions. Essentially the problem is that we have lots of code that does (especially in thunks): store.dispatch(FOO) const state = store.getState() // here we expect state to contain changes done by FOO // but with non-blocking UI this is no longer the case
- acemarke 7y agoAndrew's not wrong, but I'm also not entirely convinced it's as big of a concern as he's describing. For context, Andrew is a co-creator of Redux, and is a current React core team member. He's spent the last couple years working deeply on the "React Fiber" rewrite that became 16.0, and the "Suspense" and "Concurrent Mode" features that are now available in alpha. He's definitely right that Redux's synchronous update model is somewhat limited compared to how React's "Concurrent Mode" needs to be able to dynamically re-order state updates based on priorities. But, it remains to be seen how much of an actual problem this is in practice. Andrew's been heads-down in this feature for a long time, and so it's natural that he's seeing everything through that kind of a lens. We've got an open issue to discuss and analyze how React-Redux might be able to work better with CM and Suspense: https://github.com/reduxjs/react-redux/issues/1351 https://github.com/reduxjs/react-redux/issues/1351
- the_gipsy 7y ago
- robgibbons 7y agoThis horse has already been beaten into a bloody pulp, but Redux is so unnecessarily verbose. All due respect to the team behind it, but the DX of Redux is just horrible. I can only imagine how many developers simply gave up and became farmers because of Redux. After being subjected to the "action types" modules full of redundantly named constants, having to touch five files for a small feature, I simply use Rematch now. Its API is like cake compared to Redux, while it still satisfies the same underlying pattern for consistency/testability. "I'm going to tell my kids that Rematch was Redux"
- acemarke 7y agoAs I've pointed to a number of times throughout this thread, we created our new official Redux Toolkit package specifically to address those concerns: https://redux-toolkit.js.org https://redux-toolkit.js.org In addition, our new Style Guide docs page recommends patterns that avoid those issues as well, such as using the "ducks" file structure: https://redux.js.org/style-guide/style-guide https://redux.js.org/style-guide/style-guide